実際、私は以前の投稿に関連しています。特定のファイル拡張子を検索してディレクトリをソートするこれはまだ答えがありません。この問題を解決するにはいくつかのオプションがありますが、while
特にループに興味があります。現在の作業ディレクトリから何かをループでスキャンして特定のファイルがあるかどうかを検索し、そのwhile
フォルダ名のみを印刷したいと思います。現在、作業ディレクトリには多くのフォルダとサブフォルダがあります。これは私のスクリプトです。
while IFS= read -r d; do
if [[ "$d"=="*.out" && grep "index123"]]; then exit 1; fi
done << (find . -prune -type d)
if
強制がループ内で、または他の方法で実行する正しい方法であるかどうかわかりません。ご案内ください。
答え1
grepが失敗する理由
端末で次の操作を行います。
失敗 - 入力待機中$ grep "index123"
作業中 - STDINから入力を受け取る
$ echo -e "line1\nline2\nindex123blah\n" | grep "index123"
index123blah
2番目は、grep
STDINを介して解析された入力を提供するために機能します。grep
入力はSTDINまたはファイルから取得されます。あなたのシナリオでは:
if [[ "$d"=="*.out" && grep "index123"]]; then exit 1; fi
また、解析しないので失敗します。
あなたの問題
あなたのコードで判断すると、あなたはこのようなことをしたいと思います。まず、以下はいくつかのサンプルデータです。
$ mkdir -p 1/2/{3..5}
$ echo "index123" > 1/2/3/blah.out
$ echo "index123" > 1/2/3/blip.out
$ echo "index" > 1/2/blip.out
$ echo "index" > 1/2/blah.out
そして、スクリプトの修正された形式は次のとおりです。
$ cat loopy.bash
#!/bin/bash
while IFS= read -r d; do
grep -l "index123" "$d" && exit 1
done < <(find . -type f -name "*.out")
ランニング:
$ ./loopy.bash
./1/2/3/blah.out
index123
文字列を含む最初のファイルをエクスポートしてから終了します。
whileループのための良い解決策はありますか?
私はこれをしません。while
このようにループを使用する必要はありません。find .... | xargs ...
アーキテクチャまたはfind ... -exec
ソリューションタイプを使用することをお勧めします。
バラより@DopeGhotiの返信find
または を使用するより良い方法を得るために-exec
。xargs
インクルードディレクトリの印刷
一致するファイルを含むインクルードディレクトリツリーを印刷するには、dirname
次の手順を実行します。
$ cat loopy2.bash
#!/bin/bash
while IFS= read -r d; do
grep -q "index123" "$d" && dirname "$d" && exit 1
done < <(find . -type f -name "*.out")
そして実行してください:
$ ./loopy2.bash
./1/2/3
答え2
あなたの質問は次のとおりです。
if [[ "$d"=="*.out" && grep "index123"]];
仮説を立ててみようd=foo.out
。今、私たちは以下を効果的に持っています:
if [[ grep "index123"]];
grep
したがって、標準入力から式を検索するように指示します/index123/
。しかし、入力が届かないので、入力を待っている間に中断されるようです。しかし、if [[ grep "index123" ]]
、表面的に構文が無効であるため、それまで進行しません。代わりに、あなたは欲しいでしょうif grep "index123"
。しかし、繰り返しますが、標準入力が来るのを待っています。
find
テキストを含むファイルを返したいようです。だからこれを試してみてください:*.out
index123
find . -prune -type d -name \*.out -print0 | xargs -0 grep -l 'index123'
しかし、このfind
声明はかなり複雑です。find
必要な物理ファイルを検索できますが、なぜすべてを実行してからディレクトリをクリーンアップするのですか?
find . -type f -name \*.out -print0 | xargs -0 grep -l 'index123'
これで、探しているテキストを含むすべてのファイルが表示されます。
しかし、別々に呼び出すことxargs
ができるので、デスクトップにインポートする必要さえありません。find
grep
find . -type f -name \*.out -exec grep -l 'index123' "{}" \;
答え3
*.out
現在のディレクトリで、この文字列を含むすべてのファイルを見つけます。index123
grep -lF 'index123' ./*.out
現在のディレクトリの下のどこにいても、すべてのgrep
ファイルを繰り返し検索するには、次の手順を実行します。*.out
find . -type f -name '*.out' -exec grep -lF 'index123' {} +
文字列が見つかったディレクトリを印刷します。
find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';'
最初にディレクトリ名を見つけて終了します(GNUを使用find
)。
find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';' -quit
次の計画によって異なる使用ディレクトリ名-quit
を別の名前に変更して、必要な-exec
方法でディレクトリを操作したり、さまざまな-exec
ユーティリティをfromというシェルスクリプトに結合したりできます-exec
。あなたは何ですかいいえこれは、ディレクトリ名を別のコマンドにパイプすることです。これは、パス名を区別するためにヌル文字を使用する場合に追加の予防措置を講じない限り、通常は安全ではないためです。
関連: