だから私はコマンドラインに比較的新しいです。特定の場所がないため、findを使用して複数のディレクトリから複数のファイルの出力を取得できました(これは短縮できると確信しています)。
find ./ -name filename1.ext && find ./ -name filename2.ext && find ./ -name filename3.ext
これで、必要なもののリストが表示されましたが、問題のファイルが見つかったので、情報を得るためにそれらをgrepしたいと思います。
すべてのname
プライマリを単一のfindステートメントにグループ化してから、find execute grepを実行できます。
find . \( -name filename1.ext -o \
-name filename2.ext -o \
-name filename3.ext \) \
-exec grep 'pattern' {} \;
これを試して、
find ./ -type f \( -name filename1.ext -o -name filename2.ext -o -name filename3.ext \) -exec grep 'string' {} \;
-type f
ファイルを探しているため、結果をより早く取得するには、タイプを指定することをお勧めします。
-o
はORを意味し、検索にファイル名を追加できます
正解の横に実際に-o
および-exec
、これは前のコマンドの出力をキャプチャして行ごとに解析する一般的な方法です
(find .... && find ... && cat ... && ls ... && ...) | while read line; do grep string $line; done
一般に、find
+ grep
の組み合わせを行うには、少なくとも3つの方法があります。
grep
パターン`find
dir検索指定子-print`
find
dirfind-specifiers-exec grep
pattern{} \;
find
dirfind-specifiers-print | xargs grep
patternそしてもちろん、ここでgrep
について特別なことは何もありません。これらと同じ3つのパターンをfind
と任意のコマンドに使用できます。
ナンバー1は、ある意味で最も古く、最も基本的な方法です。なぜなら、逆引用符は常に、1つのコマンドの出力をキャプチャし、それを別のコマンドラインで使用する方法だからです。 (最近、バッククォートよりも優れた新しいバシズムがあり、すべてのクールな子供たちが使用しているという印象を受けますが、私は昔からのタイマーだと思います。)番号1の欠点は、find
大量のファイルを検索すると、「コマンドラインが長すぎます」というエラーが発生する場合があります。
番号2は、find
+コマンドの組み合わせを実行するためにfind
に組み込まれた特別な機能です。それはそれでも問題ありませんが、2つの欠点があります。(1)見つかった各ファイルに対して補助コマンド(grep
またはその他)を再度呼び出すため、遅くなる可能性があります。(2)補助コマンドはgrep
です。grep
を呼び出すたびに1つのファイル名が表示されるため、一致するファイル名はリストされませんが、-exec grep
を実行することで回避できます。 パターン{} /dev/null \;
、または最近では、-exec grep -H
パターン{} \;
。
そして、3番目です。私の知る限り、xargs
は最初の2つの制限を回避するために発明されました。 xargs
は理論的には汎用プログラムですが、実際にはfind
とgrep
以外のプログラムのペアで使用されることはほとんどないようです。 #1の欠点を完全に回避します。見つかったファイルの任意の数で動作します。それは効率的ですが、運が悪い場合は時々grep
の最後の1つのファイル名を呼び出すため、/dev/null
または-H
トリックを引き続き使用する必要があります。そして、それ自体に欠点があります。見つかったファイル名のいずれかに空白が含まれていると機能しません。しかし、それを回避する方法もあります。
find
dirfind-specifiers-print0 | xargs -0 grep
pattern
(xargs
がデフォルトで空白文字の代わりに入力で改行で区切られたファイル名を受け入れるように作成されていれば幸いですが、それは別の日の怒りです。)
bash
の使用:
shopt -s globstar
grep 'pattern' ./**/filename[123].ext
globstar
Shellオプションを有効にすると、**
パターンは*
のように動作しますが、パス名の/
全体で一致します。これは、パターンが数千のファイルと一致しない限り機能します。この場合、シェルから「引数リストが長すぎます」というエラーが発生する可能性があります。また、これは、find
が-type f
テストで行うように、一致したパス名が通常のファイル用かどうかをチェックしません。また。パターンがanythingに一致しない場合、展開されません。
上記の3つの問題すべてを解決するループで:
shopt -s globstar
for pathname in ./**/filename[123].ext; do
[ -f "$pathname" ] && grep 'pattern' /dev/null "$pathname"
done