私はファイルのどこにでも(近くにはありませんが)2つの文字列、つまり各文字列のセクション全体を見つけるための正しい構文を見つけようとしています。したがって、foo
数字と数字の両方を含むファイルは単独321
で存在する必要はなく、部分文字列にすることができ、一致する必要があります。私は運なく次を試しました。
grep 'foo\|321' *
grep 'foo|321'
答え1
GNU grep
grep
2番目のファイルはファイルリストで機能するため、少し早くする必要があります。
grep -lZ 'foo' * | xargs -0 grep -l '321'
POSIX grepと検索
find
再帰ディレクトリを検索したい場合はさらに便利です(この場合と-mindepth
オプション-maxdepth
がありません。
find . -mindepth 1 -maxdepth 1 -type f -exec grep -q 'foo' {} \; -exec grep -l '321' {} +
答え2
短いスクリプトを使用してこれを実行できます。
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
何も出力されません。
echoは、両方の文字列が同じファイルにある場合にのみ実行されます。
私はこれを行う別の方法を考えました。この方法はgrep
各ファイルを一度だけ繰り返すだけで、問題のファイルがインストールされているRAMより大きい場合はより効率的です。
for FILE in *
do
test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE
done
1行のバージョンは次のとおりです。
for FILE in *; do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE; done
答え3
奇妙な。私にとっては、両方のバリエーションが機能します(grep(GNU grep)2.13)。
grep 'foo\|321'
grep -E 'foo|321'
編集1- 一致するファイル2つのみを表示
答えは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は、より少ない数の一致を生成するものでなければなりません。
答え4
しなければならない
grep -e "foo" -e "321" *
-e を使用して複数のモードを表します。
編集する
どちらも一致する必要がある場合:
grep -e ".*foo.*321.*" *
順序が重要でない場合:
grep -e ".*foo.*321.*" ".*321.*foo.*" *