grep avec des opérateurs logiques


19

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 me rends compte 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.

grep 

Réponses:


12

Avec awk, comme avec perl, vous devrez envelopper les termes //, mais cela peut être fait:

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

28

Il existe de nombreuses façons d'utiliser grepdes opérateurs logiques.

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

    Exemple: grep 'pattern1\|pattern2' filename

  2. Utilisez l' -Eoption pour envoyer plusieurs modèles pour la condition OR .

    Exemple: grep -E 'pattern1|pattern2' filename

  3. L'utilisation d'un seul -ecorrespond à un seul modèle, mais l'utilisation de plusieurs -eoptions correspond à plusieurs modèles.

    Exemple: grep -e pattern1 -e pattern2 filename

  4. grep -vpeut simuler l' opération NOT .

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

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

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


1
-En'est pas tout à fait équivalent au &&fait qu'il est sensible à l'ordre
iruvar

grep foo | grep barest une façon plus générale de faire ET.
Kenster

2
+1 pour expliquer clairement qu'il n'y a pas de véritable opérateur "ET", et que le mieux que nous puissions faire est de simuler un hack en utilisant une structure OU. Bien sûr, cela deviendra difficile à gérer avec plus de 3 termes, mais pour deux termes, cela fonctionne bien.
Eric Hepperle - CodeSlayer2010

grep -c -e MATCH1 -e MATCH2 est idéal lorsque le nombre de noms de fichiers vous intéresse.
andrej

4

Vous pouvez utiliser perl:

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

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

Je crois que cela accomplit ce que vous essayez de faire. Il dsupprime de la sortie toute ligne qui ne correspond pas term1, il élimineb du script (et donc les impressions automatiques) toute ligne qui reste et qui correspond term2, et pour les lignes qui restent, il supprime toutes celles qui ne correspondent pas term3et de celles qui correspondent. term4.

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


0

J'utilise pour enchaîner les grepcommandes pour réaliser 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 l' -Eoption pour OR-ing et -vpour 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).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.