web-dev-qa-db-ja.com

文字列を含むが、別の文字列を含む* NOT *ファイルを一覧表示するUnixコマンド

ある文字列があり、特に別の文字列がないファイルのリストを再帰的に表示するにはどうすればよいですか?また、ファイル名ではなくファイルのテキストを評価することを意味します。


結論:

コメントごとに、私は最終的に使用しました:

find . -name "*.html" -exec grep -lR 'base\-maps' {} \; | xargs grep -L 'base\-maps\-bot'

これにより、「base-maps-bot」ではなく「base-maps」でファイルが返されました。ありがとうございました!!

30
Matrym

これを試して:

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>が含まれていない場合にのみファイル名を出力します。

42
Sander Marechal

上記の回答で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の方が高速です。各ファイルの個別のgrepプロセスではなく、1つのgrepプロセスを使用してすべてのファイルの最初のフィルターを実行するためです。

3
Tom

これらの答えは一致するように見えます[〜#〜] both [〜#〜]文字列。次のコマンドはより適切に動作するはずです。

grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'
1
Chris

より一般的な構成を次に示します。

find . -name <nameFilter> -print0 | xargs -0 grep -Z -l <patternYes> | xargs -0 grep -L <patternNo>

このコマンドは、<nameFilter>を含むが<patternYes>を含まない<patternNo>(必要に応じてfind述語を調整)と名前が一致するファイルを出力します。

機能強化は次のとおりです。

  • 空白を含むファイル名で動作します。
  • ファイルを名前でフィルタリングできます。

名前でフィルタリングする必要がない場合(多くの場合、現在のディレクトリ内のすべてのファイルを考慮したい場合)、findを削除し、最初のgrep-Rを追加できます。

grep -R -Z -l <patternYes> | xargs -0 grep -L <patternNo>
1
kirelagin

見つける。 -maxdepth 1 -name "* .py" -exec grep -L "string-not-to-match" {} \;

このコマンドは、同じディレクトリに「string-not-to-match」を含まないすべての「.py」ファイルを取得します。

0