他の文字列を含むファイルのリストから文字列を検索したいです。デフォルトでは、最初の文字列を含むファイルのリストを取得し、そのファイルから別の文字列を検索する必要があります。
次のコマンドが役立ちます。
grep -ril './' -e "first_string" | xargs grep -i "second_string"
コマンドの前半は、以下を含むファイルのリストを提供します。最初の文字列。
r
- 再帰的にディレクトリに移動
i
- 検索する文字列は大文字と小文字を区別しません。
l
- 一致するファイルのリスト
後半はこれらのファイルパスを使用し、2番目の部分を実行してgrep
ファイルに次のものがあるかどうかを検索します。2番目の文字列。
ここでは、xargs
これらのファイルをインポートして2番目のgrep
コマンドを実行する必要があります。
答え1
あなたが望むもの:
grep -rilZ 'first_string' . | xargs -r0 grep -Hi 'second_string'
GNUユーティリティ(すでにGNU拡張を使用しているため、すでに持っているようです-r
)を想定してください。
それは:
-Z
とを使用してxargs -0
パスリストを確実に渡します(Unixファミリーシステムでは、パスリストにゼロ以外のすべてのバイト値を含めることはできますが、非常に具体的な形式はxargs
必要ありません)。-0
- 最初のファイルがファイルを見つけられない場合は、
-r
forを使用してxargs
2番目のファイルの実行を避けてください(ここで省略しても問題はありません。2番目のファイルは空の標準入力をgrepにします)。grep
grep
- オプションはオプションではなく引数の前に配置する必要があります。
-H
2番目のオプションを使用して、grep
ファイル名が常に印刷されるように(最後にファイルパスのみが渡された場合でも)、一致する場所を知ることができます。grep
サポートされていない実装の場合、代替-H
案は検索する/dev/null
ファイルのリストに追加することです。その後、複数のファイル名を渡すと、常にそのファイル名が印刷されます。grep
grep
答え2
find . | perl -ne 'open($fh, $_); $s1=0; $s2=0; while($line = <$fh>) { $s1=1 if($line=~/string 1/); $s2=1 if($line=~/string 2/); } ; print $_ if($s1==1 and $s2 ==1); close $fh;' | sort | uniq
(少し長く見えますが、一行に入っています。)
編集する:いくつかの説明:
find . |
検索するディレクトリ(.
)のすべてのファイルのリストを次のコマンド(perl
)に送信します。perl -ne 'COMMANDS'
STDINから受信したすべての行(つまり、すべてのファイル)を繰り返し、COMMANDS
各行で実行されます。各ファイルの名前は常に次に終わります。$_
open($fh, $_); COMMANDS; close $fh;
ファイルを開き、filehandleにバインドし、実行してもう一度$fh
閉じCOMMANDS
ます。$s1=0; $s2=0;
次のファイルが起動されるたびに、この変数は再びゼロに設定されます。 (現在のファイルで文字列が見つかると1に設定されます。)while($line = <$fh>) { COMMANDS } ;
COMMANDS
ファイルのすべての行で実行されます。$s1=1 if($line=~/string 1/); $s2=1 if($line=~/string 2/);
string 1
現在のファイルで見つかると$s1
1になります。$s2
print $_ if($s1==1 and $s2 ==1);
文字列が見つかったら、ファイル名を印刷します。| sort | uniq
ファイル名を並べ替え、doubleをフィルタリングします(実際には必要ありません)。