grep mit logischen Operatoren

19

Gibt es ein grep-ähnliches Dienstprogramm, mit dem ich mit logischen Operatoren grep-Suchen durchführen kann? Ich möchte in der Lage sein, die logischen Konstrukte frei zu nisten und zu kombinieren. Zum Beispiel sollte so etwas möglich sein:

grep (term1 && term2) || (term1 && (term3 xor term4)) *

Mir ist klar, dass dies mit Vanilla Grep und zusätzlichem Bash-Scripting möglich ist, aber mein Ziel ist es, dies zu vermeiden.


quelle

Antworten:

12

Mit awk, wie mit perl, müssen Sie Ausdrücke einschließen //, aber es kann getan werden:

awk '(/term1/ && /term2/) || (/term1/ && xor(/term3/, /term4/))' 
muru
quelle
28

Es gibt viele Möglichkeiten, grepmit logischen Operatoren zu arbeiten.

  1. Verwenden Sie \|diese Option , um mehrere Muster für die OR- Bedingung zu trennen .

    Beispiel: grep 'pattern1\|pattern2' filename

  2. Verwenden Sie die -EOption, um mehrere Muster für die ODER- Bedingung zu senden .

    Beispiel: grep -E 'pattern1|pattern2' filename

  3. Die Verwendung einer einzelnen Option -eentspricht nur einem Muster, die Verwendung mehrerer -eOptionen entspricht jedoch mehr als einem Muster.

    Beispiel: grep -e pattern1 -e pattern2 filename

  4. grep -vkann die NICHT- Operation simulieren .

  5. Es gibt keinen AND- Operator in grep, aber Sie können AND mit Brute-Force simulieren, indem Sie die -EOption verwenden.

    Beispiel grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    Das obige Beispiel stimmt mit allen Zeilen überein , die sowohl Muster1 als auch Muster2 in beliebiger Reihenfolge enthalten.)

Thushi
quelle
1
-Eist nicht ganz gleichbedeutend mit &&aufgrund der Tatsache, dass es auftragssensitiv ist
iruvar
grep foo | grep barist eine allgemeinere Möglichkeit, UND zu tun.
Kenster,
2
+1 für die eindeutige Erklärung, dass es keinen echten "AND" -Operator gibt und dass das Beste, was wir tun können, darin besteht, einen Hack mithilfe einer OR-Struktur zu simulieren. Dies wird natürlich mit mehr als 3 Begriffen unhandlich, aber für zwei Begriffe funktioniert es gut.
Eric Hepperle - CodeSlayer2010
grep -c -e MATCH1 -e MATCH2 ist großartig, wenn Sie an der Anzahl der Dateinamen interessiert sind.
Andrej
4

Du könntest perl benutzen:

perl -wne 'print if (/term1/ && /term2/) || (/term1/ && (/term3/ xor /term4/))'
michas
quelle
0
sed '/term1/!d;/term2/b' -e '/term3/!d;/term4/d' *

Ich glaube, das erreicht, was du versuchst zu tun. Es dwird jede Zeile, die nicht übereinstimmt term1, baus der Ausgabe entfernt, alle verbleibenden und übereinstimmenden term2Zeilen werden aus dem Skript entfernt (und automatisch gedruckt) , und bei verbleibenden Zeilen werden alle nicht übereinstimmenden term3und alle übereinstimmenden Zeilen gelöschtterm4 .

sed Skripte werden nacheinander ausgewertet, und alle Tests sind boolesche Werte. Alle aus einem Test resultierenden Aktionen wirken sich daher direkt auf das Verhalten der folgenden Aktionen aus.

mikeserv
quelle
0

Ich verwende, um grepBefehle zu verketten, um ein logisches UND zu erreichen:

grep expr1 filename | grep expr2

Ich glaube, es ist ziemlich unkompliziert, Unix-artig und elegant.


Dann können Sie (wie @Tushi ausführlich erklärt) mit der -EOption zum ODER-Verknüpfen und -vzum Negieren kombinieren .

Ihr spezielles Beispiel ist ziemlich böse und würde wahrscheinlich von einem leistungsstärkeren Dienstprogramm profitieren (siehe @ murus Antwort).

Campa
quelle