回答:
grep -l string2 `grep -l string1 /path/*`
それは同じです
grep -l string2 $(grep -l string1 /path/*)
編集:なぜgrep string1 /path/* | grep string2私はalwbtcが望んでいると思うことをしないのですか?
$ cd /tmp
$ cat a
apples
oranges
bananas
$ cat b
apples
mangoes
lemons
$ cat c
mangoes
limes
pears
$ cd ~
$ grep apples /tmp/* | grep mangoes
$
何も見つかりませんでしたが、ファイルbには両方の文字列が含まれています。
これがalwbtcが望んでいるものだ
$ grep -l apples $(grep -l mangoes /tmp/*)
/tmp/b
-l両方のコマンドを同等と見なすためのオプションがありません。
パイプgrepを別のパイプに接続します。
grep "string1" /path/to/files/* | grep "string2"
RedGrittyBrickの回答と同等のackコマンドを次に示します。
ack string2 $(ack string1 -l)
同じように機能ackします(ただし、デフォルトでは現在のディレクトリを再帰的に検索します)。$()検索内のコンテンツは、その文字列が見つかったファイル名のみを検索しstring1て-l出力します。次に、それらは引数として外部コマンドに渡されます。つまり、string2これらのファイルのリスト内のみが検索されます。
comm -12 <(grep --fixed-strings --files-with-matches "STRING1" /path/to/files/* 2>/dev/null | sort) <(grep --fixed-strings --files-with-matches "STRING1" /path/to/files/* 2>/dev/null | sort)
以下の冗長性:
search_files () { str="$1"; shift; grep -Fl "$str" "$@" 2>/dev/null | sort; }
comm -12 <(search_files "STRING1" /path/to/files/*) <(sf "STRING2" /path/to/files/*)
これは、文字列が同じファイルの異なる行にある場合に機能し、ファイル名に文字列の1つが含まれている場合に誤検知を回避します。
@RedGrittyBrickのソリューションについて詳しく説明します。無人でコマンドを実行するときに欠点があり、意図したとおりにエラー出力を抑制し、ファイルを再帰的に見つけるには、次のように検討します。
grep -l 'STRING1' $(! grep -lrs 'STRING2' /absolute/path/to/search/dir && echo /dev/null)
-sオプションはエラーメッセージを抑制します
-rオプションはコマンドがハングアップしないという保証と
!組み合わせて任意にネストされたディレクトリ内の文字列を検索することを可能にします&& echo /dev/null。それ以外の場合、inner grepファイルが見つからない場合は何も出力されないため、はouter grep入力の検索を無期限に待機します。このソリューションで出力/dev/nullこれらの場合には、そうouter grepするために検索しますSTRING1で/dev/null、それが何かを見つけないことになっています場所。
私は2 つ以上の文字列を実行する拡張可能な方法を探していて、これを思いつきました:
grep -rl string1 path-to-files | xargs grep -l string2 | xargs grep -l string3
最初のgrepは、string1内に含まれるファイルの名前を再帰的に検索しますpath-to-files。
結果はパイプさxargsれ、のファイルに対して1つ以上のgrepコマンドが実行されますstring2。
その後、結果は別のxargsコマンドにパイプされます。これstring3は最初のxargs呼び出しと同じですが、別の文字列を探します。
をxargs使用すると、バックティックを使用した結果のコマンドラインが長すぎるほど多くの結果が生じる問題が回避されます。
警告を回避するには、次のようにリダイレクトstderrし/dev/nullます。
grep -rl string1 path-to-files 2>/dev/null | xargs grep -l string2
string1すでにファイル内で検出されているため、権限は良好であることがわかっているため、後続のgrep呼び出しでは必要ありません。
-lは行ではなくファイル名を返すオプションを使用しています。次に、ドル記号または逆引用符を使用して、そのリストをFILE引数として2番目のgrep に渡します。これにより、2番目のgrepは、私のソリューションのように個々の行ではなく、見つかった各ファイル全体を検索できます。