Réponses:
Eh bien, le cas générique qui fonctionne avec n'importe quelle commande qui écrit sur stdout est à utiliser xargs
, ce qui vous permettra d'attacher un nombre quelconque d'arguments de ligne de commande à la fin d'une commande:
$ find … | xargs grep 'search'
Ou pour incorporer la commande dans votre grep
ligne avec des backticks ou $()
, qui exécutera la commande et substituera sa sortie:
$ grep 'search' $(find …)
Notez que ces commandes ne fonctionnent pas si les noms de fichiers contiennent des espaces, ou certains autres «caractères étranges» ( \'"
pour xargs, \[*?
pour $(find …)
).
Cependant, dans le cas spécifique de find
la capacité à exécuter un programme sur les arguments donnés, cela est intégré:
$ find … -exec grep 'search' {} \;
Tout entre -exec
et ;
est la commande à exécuter; {}
est remplacé par le nom de fichier trouvé par find
. Cela va exécuter un grep
fichier séparé pour chaque fichier; car grep
peut prendre plusieurs noms de fichiers et les rechercher tous, vous pouvez changer le mot ;
to +
pour indiquer find afin de transmettre tous les noms de fichiers correspondants grep
à la fois:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED. Bien que -exec +
très efficace, il n’existe pas sur toutes les versions de find.
$ find … -exec grep 'search' {} \+
forme est beaucoup plus rapide.
Certaines versions de grep
(par exemple, sur Linux non intégré, BSD ou Mac OS X) ont une -r
option permettant d'effectuer une recherche récursive. Sous OpenBSD, utilisez -R
(et il n'y en a pas --exclude
comme dans l'exemple ci-dessous). Cela couvre des combinaisons simples de find
avec grep
.
Si votre implémentation ne possède pas l' -R
indicateur ou si vous souhaitez des critères de correspondance de fichiers plus élaborés, vous pouvez utiliser le -exec
principal de find
pour l'exécuter grep
. Quelques find
implémentations plus anciennes ne supportent pas -exec
… +
; sur ces systèmes, utilisez a ;
au lieu de la +
(ceci appelle grep
une fois par fichier, donc ce sera plus lent, mais sinon le résultat sera le même). Notez l' /dev/null
astuce pour que grep
le nom de fichier soit affiché même s'il est appelé sur un seul fichier (GNU grep et FreeBSD / NetBSD / OSX grep ont la -H
possibilité d'obtenir le même effet).
find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
GNU grep
a l' -H
option de toujours imprimer le nom de fichier.