web-dev-qa-db-fra.com

grep avec des opérateurs logiques

Existe-t-il un utilitaire de type grep qui me permettra de faire des recherches grep avec des opérateurs logiques. Je veux pouvoir imbriquer et combiner librement les constructions logiques. Par exemple, des trucs comme ça devraient être possibles:

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

Je sais que cela peut être fait avec Vanilla grep et des scripts bash supplémentaires, mais mon objectif ici est d'éviter d'avoir à le faire.

23
user90533

Avec awk, comme avec Perl, vous devrez encapsuler les termes dans //, Mais cela peut être fait:

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

Il existe de nombreuses façons d'utiliser grep avec des opérateurs logiques.

  1. Utilisez \| Pour séparer plusieurs modèles pour la condition OU .

    Exemple: grep 'pattern1\|pattern2' filename

  2. Utilisez l'option -E Pour envoyer plusieurs modèles pour la condition OU .

    Exemple: grep -E 'pattern1|pattern2' filename

  3. L'utilisation d'un seul -e Ne correspond qu'à un seul modèle, mais l'utilisation de plusieurs options -e Correspond à plusieurs motifs.

    Exemple: grep -e pattern1 -e pattern2 filename

  4. grep -v Peut simuler l'opération ET NON .

  5. Il n'y a pas d'opérateur ET dans grep, mais vous pouvez simuler par force brute ET en utilisant l'option -E.

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

    L'exemple ci-dessus correspondra à toutes les lignes contenant à la fois pattern1 et pattern2 dans l'un ou l'autre ordre.)

33
Thushi

Vous pouvez utiliser Perl:

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

Où les commutateurs sont les suivants:

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

J'utilise pour chaîner les commandes grep pour obtenir un ET logique:

grep expr1 filename | grep expr2

Je pense que c'est assez simple, semblable à Unix et élégant.


Ensuite, vous pouvez combiner (comme @Tushi l'a expliqué en détail) avec le -E option pour OR-ing et -v pour la négation.

Votre exemple spécifique est assez méchant et bénéficierait probablement d'un utilitaire plus puissant (voir la réponse de @ muru).

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

Je crois que cela accomplit ce que vous essayez de faire. Il deletes de sortie toute ligne qui ne correspond pas term1, il b sort du script (et donc les impressions automatiques) toute ligne qui reste et qui correspond à term2, et pour les lignes qui restent, il supprime celles qui ne correspondent pas term3 et parmi ceux qui correspondent à term4.

sed les scripts sont évalués dans l'ordre, et tous les tests sont booléens, donc toutes les actions résultant d'un test vont affecter directement le comportement des actions suivantes.

0
mikeserv