grep z operatorami logicznymi

19

Czy istnieje narzędzie podobne do grep, które umożliwi mi wyszukiwanie grep przy użyciu operatorów logicznych. Chcę mieć możliwość swobodnego zagnieżdżania i łączenia konstrukcji logicznych. Na przykład takie rzeczy powinny być możliwe:

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

Zdaję sobie sprawę, że można to zrobić za pomocą waniliowego grepa i dodatkowego skryptu bash, ale moim celem tutaj jest unikanie tego.


źródło

Odpowiedzi:

12

Tak awkjak w przypadku perl, musisz zawijać warunki //, ale można to zrobić:

awk '(/term1/ && /term2/) || (/term1/ && xor(/term3/, /term4/))' 
muru
źródło
28

Istnieje wiele sposobów korzystania grepz operatorów logicznych.

  1. Służy \|do oddzielania wielu wzorów dla warunku LUB .

    Przykład: grep 'pattern1\|pattern2' filename

  2. Użyj -Eopcji, aby wysłać wiele wzorców dla warunku LUB .

    Przykład: grep -E 'pattern1|pattern2' filename

  3. Użycie pojedynczego -edopasowania tylko jednego wzorca, ale użycie wielu -eopcji powoduje dopasowanie więcej niż jednego wzorca.

    Przykład: grep -e pattern1 -e pattern2 filename

  4. grep -vmoże symulować działanie NOT .

  5. W operatorze nie ma operatora ANDgrep , ale za pomocą opcji można symulować operację siłową AND-E .

    Przykład: grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    Powyższy przykład dopasować wszystkie linie, które zawierają zarówno wzorcowi1 i wzorzec2 w dowolnym porządku).

Thushi
źródło
1
-Enie jest do końca równoważny z &&uwagi na fakt, że jest wrażliwy na zamówienia
iruvar
grep foo | grep barjest bardziej ogólnym sposobem na wykonanie AND.
Kenster,
2
+1 za jasne wyjaśnienie, że nie ma prawdziwego operatora „ORAZ”, i że najlepiej, co możemy zrobić, to zasymulować hack przy użyciu struktury OR. Oczywiście stanie się to nieporęczne z więcej niż 3 terminami, ale dla dwóch terminów działa dobrze.
Eric Hepperle - CodeSlayer2010
grep -c -e MATCH1 -e MATCH2 jest świetny, gdy interesuje Cię liczba plików.
andrej
4

Możesz użyć perla:

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

Wierzę, że osiąga to, co próbujesz zrobić. To deletes z wyjściem każdej linii, która nie pasuje term1, to bRancza z skryptu (a więc autoprints) każdej linii, która pozostaje i który pasuje term2, a na liniach, które pozostają usuwa dowolny które nie pasują term3, a każdy z tych, które są zgodne term4.

sed skrypty są oceniane w kolejności, a wszystkie testy mają wartość logiczną, więc wszelkie działania wynikające z testu będą miały bezpośredni wpływ na zachowanie kolejnych działań.

mikeserv
źródło
0

Używam do łączenia greppoleceń w celu uzyskania logicznego AND:

grep expr1 filename | grep expr2

Uważam, że jest to dość proste, uniksowe i eleganckie.


Następnie możesz połączyć (jak dokładnie wyjaśniono @Tushi) z -Eopcją OR-ing i -vnegacji.

Twój konkretny przykład jest dość paskudny i prawdopodobnie skorzystałby z jakiegoś potężniejszego narzędzia (patrz odpowiedź @ muru).

Campa
źródło