J'utilise find
et je reçois une liste de fichiers que je veux grep
parcourir. Comment puis-je diriger cette liste vers grep
?
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.-exec
, plutôt que lexargs
. Si vous utilisez-exec
infind
, il ne créera qu'un seul shell à grep pour le contenu. Si vous utilisez lexargs
, cela créera deux coquilles: une pour lefind
et l'autre pour lexargs
.$ 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 defind
avecgrep
.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 defind
pour l'exécutergrep
. Quelquesfind
implémentations plus anciennes ne supportent pas-exec
…+
; sur ces systèmes, utilisez a;
au lieu de la+
(ceci appellegrep
une fois par fichier, donc ce sera plus lent, mais sinon le résultat sera le même). Notez l'/dev/null
astuce pour quegrep
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).la source
GNU grep
a l'-H
option de toujours imprimer le nom de fichier.