Antworten:
Sie können dies mit der Option -v
(for --invert-match
) von grep tun als:
grep -v "unwanted_word" file | grep XXXXXXXX
grep -v "unwanted_word" file
filtert die Zeilen mit dem unwanted_word
und grep XXXXXXXX
listet nur Zeilen mit Muster auf XXXXXXXX
.
BEARBEITEN:
Aus Ihrem Kommentar geht hervor, dass Sie alle Zeilen ohne das auflisten möchten unwanted_word
. In diesem Fall brauchen Sie nur:
grep -v 'unwanted_word' file
-v 'unwanted_word' --after N
hilft nicht, weil es die Zeile und N Zeilen danach enthält.
-v
oder --invert-match
wählen Sie nicht übereinstimmende Zeilen aus. In deinem Fall grep -v 'unwanted_word' file
oder grep --invert-match 'unwanted_word' file
.
git status -s |grep -v "folder_I_dont_care"
sun
, außer wenn es ist sunrise
, eine grep sun|grep -v sunrise
Zeile überspringen möchte , die beide sun
und sunrise
gleichzeitig enthält, ist das nicht das, was ich will. grep -P 'sun(?!rise)'
ist viel besser.
Ich verstand die Frage als "Wie kann ich ein Wort abgleichen, aber ein anderes ausschließen", für die eine Lösung zwei Greps in Serie sind: Erster Grep, der das gewünschte "Wort1" findet, zweiter Grep, der "Wort2" ausschließt:
grep "word1" | grep -v "word2"
In meinem Fall: Ich muss zwischen "plot" und "#plot" unterscheiden, was die Option "word" von grep nicht tut ("#" ist keine alphanumerische Zahl).
Hoffe das hilft.
word1
.
Wenn Sie grep
den regulären Perl-Ausdruck mit -P
Option unterstützen, können Sie dies tun (wenn bash; wenn tcsh, müssen Sie dem entkommen !
):
grep -P '(?!.*unwanted_word)keyword' file
Demo:
$ cat file
foo1
foo2
foo3
foo4
bar
baz
Lassen Sie uns jetzt alle foo
außer auflistenfoo3
$ grep -P '(?!.*foo3)foo' file
foo1
foo2
foo4
$
grep -v -P
auch im regulären Ausdruck ohne Negation funktioniert.
!
" . Danke danke danke! Das wollte ich!
Die richtige Lösung ist die Verwendung grep -v "word" file
mit dem awk
Äquivalent:
awk '!/word/' file
Wenn Sie jedoch eine komplexere Situation haben, in der Sie beispielsweise XXX
erscheinen und YYY
nicht erscheinen möchten, ist dies awk
praktisch, anstatt mehrere grep
s zu leiten :
awk '/XXX/ && !/YYY/' file
# ^^^^^ ^^^^^^
# I want it |
# I don't want it
Sie können sogar etwas komplexeres sagen. Zum Beispiel: Ich möchte diese Zeilen, die entweder XXX
oder enthalten YYY
, aber nicht ZZZ
:
awk '(/XXX/ || /YYY/) && !/ZZZ/' file
usw.
grep -P
Lösung für große Dateien.
grep -P
bedeutet die Verwendung von Perl-Regexp. Das Laden dieses Pakets ist also weitaus teurer als normal grep
.
grep bietet die Option '-v' oder '--invert-match', um nicht übereinstimmende Zeilen auszuwählen.
z.B
grep -v 'unwanted_pattern' file_name
Dadurch werden alle Zeilen aus der Datei Dateiname ausgegeben, die kein unerwünschtes Muster enthält.
Wenn Sie das Muster in mehreren Dateien in einem Ordner suchen, können Sie die rekursive Suchoption wie folgt verwenden
grep -r 'wanted_pattern' * | grep -v 'unwanted_pattern'
Hier versucht grep, alle Vorkommen von 'want_pattern' in allen Dateien aus dem aktuellen Verzeichnis aufzulisten und an den zweiten grep zu übergeben, um das 'unerwünschte_Muster' herauszufiltern. '|' - Pipe weist die Shell an, die Standardausgabe des linken Programms (grep -r 'want_pattern' *) mit der Standardeingabe des rechten Programms (grep -v 'unerwünschtes_muster') zu verbinden.
Ich habe ein Verzeichnis mit einer Reihe von Dateien. Ich möchte alle Dateien finden, die NICHT die Zeichenfolge "speedup" enthalten, daher habe ich den folgenden Befehl erfolgreich verwendet:
grep -iL speedup *
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"