上記の回答で xargs を使用する必要はありません。次のように同じことを達成できます:
find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print
grep -q
静かに実行するが、一致が見つかったかどうかを示す終了コードを返すことを意味します。 find
次に、その終了コードを使用して、残りのオプションを実行し続けるかどうかを決定できます。 -exec grep -q <string-to-match> {} \;
の場合 0 を返し、次に -not -exec grep -q <string-not-to-match>{} \;
を実行します .それも 0 を返す場合、-print
を実行します。 、ファイルの名前を出力します。
find
を使用して、別の回答が指摘したように この方法では、grep -Rl
よりも大きな利点があります 特定のタイプのファイルのみを検索したい場合。一方、本当にすべてのファイルを検索したい場合は、 grep -Rl
1 つの grep
を使用するため、おそらくより高速です。 個別の grep
の代わりに、すべてのファイルに対して最初のフィルターを実行するプロセス ファイルごとに処理します。
これを試してください:
grep -rl <string-to-match> | xargs grep -L <string-not-to-match>
説明:grep -lr
grep を再帰的に (r) <string-to-match>
を含むすべてのファイルのリスト (l) を出力します。 . xargs はこれらのファイルをループし、grep -L
を呼び出します。 それらのそれぞれに。 grep -L
ファイルに <string-not-to-match>
が含まれていない場合にのみファイル名を出力します .
これらの答えは 両方 一致していないようです 文字列。次のコマンドはより適切に機能するはずです:
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'