Correspondance négative à l'aide de grep (correspond à des lignes qui ne contiennent pas foo)


991

J'ai essayé de trouver la syntaxe de cette commande:

grep ! error_log | find /home/foo/public_html/ -mmin -60

OU:

grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60

J'ai besoin de voir tous les fichiers qui ont été modifiés à l'exception de ceux nommés error_log.

J'ai lu à ce sujet ici , mais je n'ai trouvé qu'un notseul motif -regex.


13
[^ error_log] ne fonctionnerait jamais de toute façon, [] sont des classes de caractères, les expressions rationnelles en général ne sont pas bonnes pour les modèles négatifs (sauf si le moteur implémente des lookaheads négatifs).
Jaap

Réponses:


1758

grep -v est votre ami:

grep --help | grep invert  

-v, --invert-match sélectionner les lignes non correspondantes

Consultez également les connexes -L(le complément de -l).

-L, --files-without-match uniquement affiche les noms de FICHIER ne contenant aucune correspondance


125
Il convient de mentionner que pour plusieurs matchs (négatifs), l' -eoption peut être utilisée:grep -v -e 'negphrase1' -e 'negphrase2'
Babken Vardanyan

31
Semblable au commentaire de @ Babken-Vardanyan Aussi - capable d'utiliser des tuyaux pour rejoindre plusieurs matchs, par exemplegrep -v 'negphrase1|negphrase2|negphrase3'
Nicholas Adams

13
Le dernier commentaire n'est PAS le même car il recherchera des choses qui ne correspondent pas aux deux plutôt qu'aux deux. c'est-à-dire s'il correspond à l'un mais pas à l'autre, il est toujours imprimé. Essayez-le dans les deux sens avec des cordes non similaires
Evan Langlois

7
@EvanLanglois - forçant grep à interpréter le motif comme une expression régulière étendue à l'aide d' -Eœuvres, c'estgrep -vE 'negphrase1|negphrase2|negphrase3'
Zlemini

1
@ OlleHärstedt, je pense que j'ai mal compris votre scénario dans mon commentaire précédent, ce qui suit peut être ce que vous recherchez grep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -u( pourquoi le premier grep?, Il y a toujours un moyen :))
Motti

139

Vous pouvez également utiliser awkà ces fins, car il vous permet d'effectuer des vérifications plus complexes d'une manière plus claire:

Lignes ne contenant pas foo:

awk '!/foo/'

Lignes ne contenant ni fooni bar:

awk '!/foo/ && !/bar/'

Les lignes ne contenant ni fooni barqui contiennent soit foo2ou bar2:

awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)'

Etc.


2
C'est plutôt cool. Vous n'avez même pas besoin d'apprendre le langage awk complet pour regrouper l'expression rationnelle avec des opérateurs logiques. Merci pour cette réponse!
Peter T.

1
Exactement ce que je cherchais, merci beaucoup.
mmrs151

13

Dans votre cas, vous ne voulez probablement pas utiliser grep, mais ajoutez à la place une clause négative à la commande find, par exemple

find /home/baumerf/public_html/ -mmin -60 -not -name error_log

Si vous souhaitez inclure des caractères génériques dans le nom, vous devrez les échapper, par exemple pour exclure les fichiers avec le suffixe .log:

find /home/baumerf/public_html/ -mmin -60 -not -name \*.log
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.