Negative Übereinstimmung mit grep (Übereinstimmungslinien, die kein foo enthalten)

990

Ich habe versucht, die Syntax für diesen Befehl zu erarbeiten:

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

ODER:

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

Ich muss alle Dateien sehen, die geändert wurden, außer den genannten error_log.

Ich habe hier darüber gelesen , aber nur ein notRegex-Muster gefunden.

jerrygarciuh
quelle
13
[^ error_log] würde sowieso nie funktionieren, [] sind Zeichenklassen, reguläre Ausdrücke sind im Allgemeinen nicht gut in negativen Mustern (es sei denn, die Engine implementiert negative Lookaheads).
Jaap

Antworten:

1756

grep -v ist dein Freund:

grep --help | grep invert  

-v, --invert-match wählt nicht übereinstimmende Zeilen aus

Überprüfen Sie auch die verwandten -L(die Ergänzung von -l).

-L, --files-without-match druckt nur DATEINamen, die keine Übereinstimmung enthalten

Motti
quelle
125
Erwähnenswert ist, dass für mehrere (negative) Spiele die -eOption verwendet werden kann:grep -v -e 'negphrase1' -e 'negphrase2'
Babken Vardanyan
31
Ähnlich dem Kommentar von @ Babken-Vardanyan Auch - in der Lage, Pipes zu verwenden, um mehrere Spiele zu verbinden, zBgrep -v 'negphrase1|negphrase2|negphrase3'
Nicholas Adams
13
Der letzte Kommentar ist NICHT derselbe, da nach Dingen gesucht wird, die nicht mit beiden übereinstimmen, sondern mit beiden. dh wenn es mit dem einen übereinstimmt, aber nicht mit dem anderen, wird es immer noch gedruckt. Versuchen Sie es in beide Richtungen mit nicht ähnlichen Zeichenfolgen
Evan Langlois
7
@EvanLanglois - Grep zwingen, das Muster als erweiterten regulären Ausdruck unter Verwendung von -EWerken zu interpretieren , dh grep -vE 'negphrase1|negphrase2|negphrase3'
Zlemini
1
@ OlleHärstedt, ich glaube, ich habe Ihr Szenario in meinem vorherigen Kommentar falsch verstanden. Folgendes könnte das sein, wonach Sie suchen grep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -u( warum der erste Grep? Es gibt immer einen Weg :))
Motti
139

Sie können auch awkfür diese Zwecke verwenden, da Sie damit komplexere Überprüfungen klarer durchführen können:

Zeilen, die nicht enthalten foo:

awk '!/foo/'

Zeilen, die weder foonoch enthalten bar:

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

Zeilen, die weder foonoch barenthalten foo2oder entweder oder enthalten bar2:

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

Und so weiter.

fedorqui 'SO hör auf zu schaden'
quelle
2
Das ist eigentlich ziemlich cool. Sie müssen nicht einmal die vollständige awk-Sprache lernen, um Regexp mit logischen Operatoren zu gruppieren. Danke für diese Antwort!
Peter T.
1
Genau das, wonach ich gesucht habe, vielen Dank.
mmrs151
13

In Ihrem Fall möchten Sie vermutlich nicht grep verwenden, sondern dem Befehl find stattdessen eine negative Klausel hinzufügen, z

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

Wenn Sie Platzhalter in den Namen aufnehmen möchten, müssen Sie diese maskieren, z. B. um Dateien mit dem Suffix .log auszuschließen:

find /home/baumerf/public_html/ -mmin -60 -not -name \*.log
Papa Schlumpf
quelle