Ich versuche, eine grep-Suche zu erstellen, die nach einem Begriff sucht, aber Zeilen ausschließt, die einen zweiten Begriff haben. Ich wollte mehrere -e "pattern"
Optionen verwenden, aber das hat nicht funktioniert.
Hier ist ein Beispiel für einen Befehl, den ich ausprobiert habe, und die von ihm generierte Fehlermeldung.
grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory
Mir ist klar, dass das -v
für alle Suchbegriffe / Suchmuster gilt. Da läuft das dann aber nicht search term
in den Ergebnissen mit.
grep -i -E "search term" -ve "exclude term"
Antworten:
Für und Ausdrücke mit grep benötigen Sie zwei Aufrufe:
Wenn es sich bei den gesuchten Begriffen nicht um reguläre Ausdrücke handelt, verwenden Sie eine feste Zeichenfolge (
-F
), die schneller ist:quelle
Ohne zweimal grep aufzurufen, gibt es nur einen Weg, dies zu erreichen. Es handelt sich um Perl-kompatible reguläre Ausdrücke (PCRE) und einige ziemlich hacky Look-Around-Behauptungen .
Um nach foo mit Ausnahme von Übereinstimmungen zu suchen , die eine Leiste enthalten , können Sie Folgendes verwenden:
So funktioniert das:
(?!bar)
Stimmt mit allem überein, was nicht gesperrt ist, ohne Zeichen aus der Zeichenfolge zu verbrauchen. Dann.
verbraucht ein einzelnes Zeichen.^((?!bar).)*
wiederholt das Obige vom Anfang der Zeichenkette (^
) bis zum Ende ($
). Es schlägt fehl, wennbar
es an einem bestimmten Punkt auftritt, da(?!bar)
es nicht übereinstimmt.(?=^((?!bar).)*$)
Stellt sicher, dass die Zeichenfolge mit dem vorherigen Muster übereinstimmt, ohne dass Zeichen aus der Zeichenfolge verwendet werden.foo
sucht wie gewohnt nach foo .Ich habe gefunden, dass dieser Hack im regulären Ausdruck mit einer Zeichenfolge übereinstimmt, die kein Wort enthält. . In der Antwort von Bart Kiers finden Sie eine viel detailliertere Erklärung, wie die negative Vorausschau funktioniert.
quelle
Wenn Sie dies in einem Durchgang tun möchten, können Sie awk anstelle von grep verwenden.
Format:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
Beispiele:
echo "hello there" | awk '/hello/ && !/there/'
Gibt nichts zurück.
echo "hello thre" | awk '/hello/ && !/there/'
Rückgabe: hallo thre
echo "hllo there" | awk '/hello/ && !/there/'
Gibt nichts zurück.
Bei mehreren Mustern können Sie sie mithilfe von Klammern gruppieren.
Beispiele:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
Rückgabe: hallo thre
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
Rückgabe: hi thre
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
Gibt nichts zurück.
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
Gibt nichts zurück.
quelle
ls --color=always | awk '/hello/ && !/goodbye/'
grep -R
in mehreren Codedateien mithilfe der Ubuntu-Befehlszeile gefunden habe.Aus meinen Experimenten macht es keinen großen Unterschied, ob Sie Ihre Ausschlussbedingungen durch
grep
oder leitensed
. Sed hat einige andere nützliche Funktionen zum Ersetzen von Text, die ich oft benutze, um die Ausgabe von Protokolldateien besser zu filtern. Also werde ich sed verwenden, da ich eine ganze Reihe von Filtern auf sed kombiniere.quelle
grep -F
stattdessen die Laufzeit vongrep -E
und verwenden Sie sie nicht,-i
wenn Sie sie nicht benötigen.sed
;)