grepを使用した否定一致(fooを含まない行に一致)


990

私はこのコマンドの構文を理解しようとしています:

grep ! error_log | find /home/foo/public_html/ -mmin -60

または:

grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60

という名前のファイルを除いて、変更されたすべてのファイルを表示する必要がありますerror_log

私はそれについてここ読みましたが、1つのnot-regexパターンしか見つかりませんでした。


13
[^ error_log]は決して機能しません。[]はcharクラスです。正規表現は一般に否定的なパターンには適していません(エンジンが否定的な先読みを実装しない限り)。
Jaap

回答:


1757

grep -v あなたの友だちです:

grep --help | grep invert  

-v、--invert-match一致しない行を選択します

また、関連-L(の補足-l)も確認してください。

-L、--files-without-match一致を含まないFILE名のみを出力します


125
複数の(否定的な)一致-eオプションを使用できることに言及する価値がある:grep -v -e 'negphrase1' -e 'negphrase2'
Babken Vardanyan '18

31
@ Babken-Vardanyanからのコメントに似ています-パイプを使用して複数の試合に参加することもできます。例grep -v 'negphrase1|negphrase2|negphrase3'
Nicholas Adams

13
最後のコメントは、どちらかではなく両方に一致しないものを検索するため、同じではありません。つまり、一方が一致し、もう一方が一致しない場合は、まだ印刷されます。似ていない文字列で両方の方法で試してください
Evan Langlois

7
@EvanLanglois -使用して、拡張正規表現としてパターンを解釈するためにはgrepを強制-Eすなわち、作品を grep -vE 'negphrase1|negphrase2|negphrase3'
Zlemini

1
@OlleHärstedt、私は以前のコメントであなたのシナリオを誤解したと思います、以下はあなたが探しているものかもしれませんgrep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -uなぜ最初のgrepですか?、常に方法があります:))
Motti

139

awkより複雑なチェックをより明確に実行できるため、これらの目的にも使用できます。

次を含まない行foo

awk '!/foo/'

どちらも含まない行foobar

awk '!/foo/ && !/bar/'

を含まない、またはどちらfooも含まない行:barfoo2bar2

awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)'

等々。


2
それは実際にはかなりクールです。論理演算子で正規表現をグループ化するために、完全なawk言語を学ぶ必要すらありません。この回答をありがとう!
ピーターT.

1
まさに私が探していたものに感謝します。
mmrs151

13

あなたの場合、おそらくgrepを使いたくないでしょうが、代わりにfindコマンドに否定句を追加します。

find /home/baumerf/public_html/ -mmin -60 -not -name error_log

名前にワイルドカードを含めたい場合は、それらをエスケープする必要があります。たとえば、拡張子が.logのファイルを除外します。

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