grep con operatori logici


19

Esiste un'utilità simile a grep che mi permetterà di fare ricerche grep con operatori logici. Voglio essere in grado di nidificare e combinare liberamente i costrutti logici. Ad esempio, cose come questa dovrebbero essere possibili:

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

Mi rendo conto che questo può essere fatto con vanilla grep e script bash aggiuntivi, ma il mio obiettivo qui è quello di evitare di farlo.

grep 

Risposte:


12

Con awk, come con perl, dovrai racchiudere i termini //, ma si può fare:

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

28

Esistono molti modi per utilizzare grepgli operatori logici.

  1. Utilizzare \|per separare più motivi per la condizione OR .

    Esempio: grep 'pattern1\|pattern2' filename

  2. Utilizzare l' -Eopzione per inviare più pattern per la condizione OR .

    Esempio: grep -E 'pattern1|pattern2' filename

  3. L'uso di un singolo -ecorrisponde a un solo modello, ma l'utilizzo di più -eopzioni corrisponde a più di un modello.

    Esempio: grep -e pattern1 -e pattern2 filename

  4. grep -vpuò simulare l' operazione NOT .

  5. Non è presente alcun operatore AND in grep, ma è possibile simulare AND con forza bruta utilizzando l' -Eopzione.

    Esempio : grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    L'esempio sopra abbinerà tutte le linee che contengono sia pattern1 che pattern2 in entrambi i ordini.)


1
-Enon è del tutto equivalente a &&causa del fatto che è sensibile
all'ordine

grep foo | grep barè un modo più generale di fare AND.
Kenster,

2
+1 per spiegare chiaramente che non esiste un vero operatore "AND" e che il meglio che possiamo fare è simulare un hack utilizzando una struttura OR. Questo ovviamente diventerà ingombrante con più di 3 termini, ma per due termini funziona bene.
Eric Hepperle - CodeSlayer2010,

grep -c -e MATCH1 -e MATCH2 è ottimo quando sei interessato al conteggio dei nomi dei file.
Andrej

4

Puoi usare perl:

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

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

Credo che compia ciò che stai cercando di fare. Si deletes dall'uscita tutte le linee che non corrisponde term1, si branch fuori dello script (e così autoprints) qualsiasi linea che resti e che le partite term2, e per le linee che rimangono elimina qualsiasi che non corrispondono term3e da quelli che lo fanno ogni partita term4.

sed gli script vengono valutati in ordine e tutti i test sono booleani, quindi qualsiasi azione risultante da un test influirà direttamente sul comportamento di qualsiasi azione successiva.


0

Uso i grepcomandi a catena per ottenere un AND logico:

grep expr1 filename | grep expr2

Credo che sia piuttosto semplice, simile a Unix ed elegante.


Quindi puoi combinare (come spiegato a fondo @Tushi) con l' -Eopzione per OR-ing e -vper negare.

Il tuo esempio specifico è piuttosto brutto e probabilmente trarrebbe beneficio da qualche utilità più potente (vedi la risposta di @ muru).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.