find
課題には、実際にコマンドを使用せずに非常に基本的なbashスクリプトとして機能するbashスクリプトを作成する必要がありますfind
。たとえば、次のように入力すると:
my_find ~/homedir/ -name 'test*' -name '*.o' -type f
~/homedir/
ワイルドカード名と一致するものを検索し、その結果内で名前と一致するものを検索し、最後に(おそらく重複する可能性がある)ファイルを検索するために必要です。最後に、すべての結果がリストされます。test*
AND
*.o
dirpath=$1
これまで、ディレクトリパス()を格納する変数を作成しました。次に、それを使用してshift
最初の引数を削除し、次の手順を実行します(注、-type
まだ実装されていません)。
while (($#)); do
if [[ $1 == "-name" ]]; then
# process the name here?
shift 2 # get rid of -name "name"
fi
done
これをどうやって作るのか、それともどうするのか気になります。ディレクトリパスを介して繰り返される部分的に完了した関数がありますが、渡された引数を処理する方法/場所がわかりません。これは各ディレクトリを調べる再帰関数です。
recurse_path () {
for i in "$@"; do
# process and store matching file names in the array?
if [[ -d "${i}" ]]; then
cd "${i}"
recurse_path *
fi
done
}
それでは、この機能を使用するときに一致するファイル名を検索して結果を配列に保存するにはどうすればよいですか?また、これが正しい方法ですか、それとも各コマンドを表示したときに得られた結果を更新するより簡単な方法はありますか?私はbashスクリプトに初めて触れたので、アドバイスをいただきありがとうございます。
答え1
基本的なものを注文してみましょう。
1.
すでにディレクトリツリーを参照できる場合は、次のステップは現在アクセスしているディレクトリ内を検索することです。サポートするパターンの構文スタイルによって異なります。正規表現はまったく異なるものです。たぶん、私たちはシェルの組み込みパターン構文に満足するかもしれません。じゃあそれだ。
for i in * ; do for p in <patterns> ; do
if [[ $i == $p ]]
...
fi
done ; done
2.
コマンドラインを解析するには、bashにgetoptが組み込まれています。マニュアルを参照してください。
三。
配列については、マニュアルを参照してください。
答え2
ダーティソリューションは次のとおりです。
boolRememberNext=0
rememberString=""
for arg in $*; do
if [ ${boolRememberNext} -eq 1 ]; then
rememberString="${rememberString} ${arg}"
fi
if [ "${arg}" = "-name" ]; then
boolRememberNext=1
else
boolRememberNext=0
fi
done
echo ${rememberString} | while read filemask; do
unquotedFile=$(echo "$filemask" | tr -d "'")
ls -R1 ~/homedir/ | grep ":" | cut -d: -f1 | while read dir; do
ls ${dir}/unquotedFile
done
done
なぜ汚いの?
- ループが多く、ファイルシステムに複数回アクセスする
- 無効なコマンドライン構文を無視
- ディレクトリとファイル名には次のものを含めることはできません。
- trを使用してvarを逆参照すると、*組み合わせは処理されません。
これについてはevalを使用したくありません。
ソリューションを改善するためにどのような措置を講じることができますか?
中間結果をローカル変数に保存し、特殊文字処理を改善し、構文を確認できます。
また、ls ~/homedir/*
ファイルが見つからないまで検索パスにアスタリスクを追加することもできます。いくつかのフィルタ(awk?)を介してすべてのファイルを解析します。見つかったファイルを確認してください。ディレクトリではないファイルです。