Linuxで2つの文字列を一緒に含むファイルを見つける方法は?


11

2つの文字列を一緒に含むファイルを検索したい。たとえば、ファイルにとの両方が含まれstring1ているstring2

出力にファイルの完全パスが必要です。「許可が拒否されました」という警告は表示したくない。

回答:


15
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

1
これはきちんとしたソリューションであり、私のものよりも便利です。ここで何が行われているのかを知りたい(少し理解するのに少し時間がかかりました)ために、彼-lは行ではなくファイル名を返すオプションを使用しています。次に、ドル記号または逆引用符を使用して、そのリストをFILE引数として2番目のgrep に渡します。これにより、2番目のgrepは、私のソリューションのように個々の行ではなく、見つかった各ファイル全体を検索できます。
embedded.kyle

-l両方のコマンドを同等と見なすためのオプションがありません。
2013

2

パイプgrepを別のパイプに接続します。

grep "string1" /path/to/files/* | grep "string2"


5
2つの文字列がファイルの異なる行にある場合、これは機能しません。
RedGrittyBrick

1
彼らが同じ行にいる必要があることを知りませんでした@RedGrittyBrick
slhck

@slhck:alwbtcが何を望んでいるのか、なぜこの回答ではそれができないのかを示すために、回答を更新しました。もちろん、alwbtcが何を求めているのかを誤解している可能性があり、embedded.kyleが正しく理解している可能性があります。
RedGrittyBrick

1

RedGrittyBrickの回答と同等のコマンドを次に示します

ack string2 $(ack string1 -l)

同じように機能ackします(ただし、デフォルトでは現在のディレクトリを再帰的に検索します)。$()検索内のコンテンツは、その文字列が見つかったファイル名のみを検索しstring1-l出力します。次に、それらは引数として外部コマンドに渡されます。つまり、string2これらのファイルのリスト内のみが検索されます。


0
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つが含まれている場合に誤検知を回避します。


0

@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、それが何かを見つけないことになっています場所。


0

私は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呼び出しでは必要ありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.