GNU grep

GNU grep

私はファイルのどこにでも(近くにはありませんが)2つの文字列、つまり各文字列のセクション全体を見つけるための正しい構文を見つけようとしています。したがって、foo数字と数字の両方を含むファイルは単独321で存在する必要はなく、部分文字列にすることができ、一致する必要があります。私は運なく次を試しました。

grep 'foo\|321' *

grep 'foo|321'

答え1

GNU grep

grep2番目のファイルはファイルリストで機能するため、少し早くする必要があります。

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.*" *

関連情報