私は、ファイル内の2つの文字列(各文字列の全体)をどこでも(相互に近接している必要はありません)見つけるための正しい構文を理解しようとしています。したがって、foo
と番号321
の両方を含むファイルは、単独である必要はなく、部分文字列でもかまいません。私は運が悪いのに以下を試しました:
grep 'foo\|321' *
grep 'foo|321'
2番目のgrep
はファイルのリストを操作する可能性があるため、少し高速になるはずです。
grep -lZ 'foo' * | xargs -0 grep -l '321'
find
は、再帰ディレクトリを検索する場合に便利です(この場合、-mindepth
および-maxdepth
オプション。
find . -mindepth 1 -maxdepth 1 -type f -exec grep -q 'foo' {} \; -exec grep -l '321' {} +
あなたは短いスクリプトでこれを行うことができます:
for FILE in *
do
grep -q foo $FILE && grep -q 321 $FILE && echo $FILE
done
これを1行で行うこともできます。
for FILE in *; do grep -q foo $FILE && grep -q 321 $FILE && echo $FILE; done
grep
は、文字列が見つかった場合は0(true)を返し、コマンドを&&
で区切ると、最初のコマンドがtrueの場合にのみ2番目のコマンドが実行されます。 -q
オプションは、grep
が何も出力しないようにします。
エコーは、両方の文字列が同じファイルで見つかった場合にのみ実行されます。
別の方法を考えました。この方法は、問題のファイルがインストールしたRAMよりも大きい場合、各ファイルを1回だけgrep
する必要があるため、より効率的です。
for FILE in *
do
test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE
done
そして一行バージョン:
for FILE in *; do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE; done
奇妙な。私にとっては両方のバリアントが機能します(grep(GNU grep)2.13):
grep 'foo\|321'
grep -E 'foo|321'
編集1-両方が一致するファイルのみを表示
for file in *
回答は機能しますが、パフォーマンスの悪夢になる可能性があります(大量のファイルの場合):ファイルごとに少なくとも2つのプロセス。これはより高速です(GNU世界では):
find . -type f -print0 | xargs -0 -r grep --files-with-matches --null -- string1 |
xargs -0 -r grep --files-with-matches -- string2
string1は、一致が少なくなるものでなければなりません。
基本的に、ディレクトリ内の特定の文字列を含むすべてのファイルを検索するには、次を使用できます。
grep -lir "pattern" /path/to/the/dir
-l
:このスキャンを行うには、最初の一致で停止します-i
:パターンと入力ファイルの両方で大文字と小文字の区別を無視します-r
:ディレクトリの下のすべてのファイルを再帰的に検索します2つのパターンを検索するには、次のことを試してください。
grep -lr "321" $(grep -lr "foo" /path/to/the/dir)