it-swarm.com.de

grep mit logischen Operatoren

Gibt es ein grep-ähnliches Dienstprogramm, mit dem ich grep-Suchen mit logischen Operatoren durchführen kann? Ich möchte in der Lage sein, die logischen Konstrukte frei zu verschachteln 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 hier ist es, dies zu vermeiden.

23
user90533

Mit awk müssen Sie wie mit Perl Begriffe in // Umschließen, aber es geht:

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

Es gibt viele Möglichkeiten, grep mit logischen Operatoren zu verwenden.

  1. Verwenden \|, um mehrere Muster für die Bedingung ODER zu trennen.

    Beispiel: grep 'pattern1\|pattern2' filename

  2. Verwenden Sie die -E Option zum Senden mehrerer Muster für die Bedingung ODER .

    Beispiel: grep -E 'pattern1|pattern2' filename

  3. Verwenden eines einzelnen -e entspricht nur einem Muster, verwendet jedoch mehrere -e Option entspricht mehr als einem Muster.

    Beispiel: grep -e pattern1 -e pattern2 filename

  4. grep -v kann die Operation NICHT simulieren.

  5. Es gibt keinen Operator UND in grep, aber Sie können Brute-Force-Simulationen [~ # ~] und [~ #] durchführen. ~] mit dem -E Möglichkeit.

    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.)

33
Thushi

Sie könnten Perl verwenden:

Perl -wne 'print if (/term1/ && /term2/) || (/term1/ && (/term3/ xor /term4/))'

Wo die Schalter sind wie folgt:

-w turns on warnings
-n runs Perl against each line of input (looping)
-e executes Perl passed in the command line
5
michas

Ich verkette grep Befehle, um ein logisches UND zu erreichen:

grep expr1 filename | grep expr2

Ich glaube, es ist ziemlich einfach, Unix-ähnlich und elegant.


Dann können Sie (wie @Tushi ausführlich erklärt) mit der Option -E Zum ODER-Verknüpfen und -v Zum Negieren kombinieren.

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

0
Campa
sed '/term1/!d;/term2/b' -e '/term3/!d;/term4/d' *

Ich glaube, das erreicht das, was Sie versuchen zu tun. Es d löscht aus der Ausgabe jede Zeile, die nicht mit term1 Übereinstimmt, es b ranchiert aus dem Skript (und damit Autoprints) jede verbleibende Zeile und das stimmt mit term2 überein, und für verbleibende Zeilen werden alle gelöscht, die nicht mit term3 übereinstimmen, und diejenigen, die mit term4 übereinstimmen.

sed Skripte werden der Reihe nach ausgewertet, und alle Tests sind boolesch. Daher wirken sich alle aus einem Test resultierenden Aktionen direkt auf das Verhalten der folgenden Aktionen aus.

0
mikeserv