L'utilisation de xargs dans les réponses ci-dessus n'est pas nécessaire; vous pouvez obtenir la même chose comme ceci :
find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print
grep -q
signifie exécuter silencieusement mais renvoyer un code de sortie indiquant si une correspondance a été trouvée ; find
peut ensuite utiliser ce code de sortie pour déterminer s'il faut continuer à exécuter le reste de ses options. Si -exec grep -q <string-to-match> {} \;
renvoie 0, puis il continuera à exécuter -not -exec grep -q <string-not-to-match>{} \;
. Si cela renvoie également 0, il continuera à exécuter -print
, qui imprime le nom du fichier.
Comme une autre réponse l'a noté, en utilisant find
présente ainsi des avantages majeurs par rapport à grep -Rl
où vous souhaitez uniquement rechercher des fichiers d'un certain type. Si, par contre, vous voulez vraiment rechercher tous les fichiers, grep -Rl
est probablement plus rapide, car il utilise un grep
processus pour effectuer le premier filtre pour tous les fichiers, au lieu d'un grep
séparé processus pour chaque fichier.
Essayez ceci :
grep -rl <string-to-match> | xargs grep -L <string-not-to-match>
Explication :grep -lr
fait en sorte que grep produise de manière récursive (r) une liste (l) de tous les fichiers contenant <string-to-match>
. xargs boucle sur ces fichiers, appelant grep -L
sur chacun d'eux. grep -L
n'affichera le nom du fichier que si le fichier ne contient pas <string-not-to-match>
.
Ces réponses semblent correspondre à BOTH cordes. La commande suivante devrait mieux fonctionner :
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'