whileループで特定の検索でファイルを検索する[閉じる]

whileループで特定の検索でファイルを検索する[閉じる]

実際、私は以前の投稿に関連しています。特定のファイル拡張子を検索してディレクトリをソートするこれはまだ答えがありません。この問題を解決するにはいくつかのオプションがありますが、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番目は、grepSTDINを介して解析された入力を提供するために機能します。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または を使用するより良い方法を得るために-execxargs

インクルードディレクトリの印刷

一致するファイルを含むインクルードディレクトリツリーを印刷するには、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テキストを含むファイルを返したいようです。だからこれを試してみてください:*.outindex123

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ができるので、デスクトップにインポートする必要さえありません。findgrep

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。あなたは何ですかいいえこれは、ディレクトリ名を別のコマンドにパイプすることです。これは、パス名を区別するためにヌル文字を使用する場合に追加の予防措置を講じない限り、通常は安全ではないためです。

関連:

関連情報