xargs prend son entrée standard et la transforme en arguments de ligne de commande.
find . -name '*.c' | xargs grep 'stdlib.h'
est très similaire à
grep 'stdlib.h' $(find . -name '*.c') # UNSAFE, DON'T USE
Et donnera les mêmes résultats tant que la liste des noms de fichiers n'est pas trop longue pour une seule ligne de commande. (Linux prend en charge des mégaoctets de texte sur une seule ligne de commande, donc vous n'avez généralement pas besoin de xargs.)
Mais ces deux choses sont nulles, car elles se cassent si vos noms de fichiers contiennent des espaces . Au lieu de cela, find -print0 | xargs -0
fonctionne, mais il en va de même
find . -name '*.c' -exec grep 'stdlib.h' {} +
Cela ne find
dirige jamais les noms de fichiers n'importe où: les regroupe dans une grande ligne de commande et s'exécutegrep
directement.
\;
au lieu d' +
exécuter grep séparément pour chaque fichier, ce qui est beaucoup plus lent. Ne fais pas ça. Mais +
c'est une extension GNU, vous devez xargs
donc le faire efficacement si vous ne pouvez pas supposer que GNU trouve.
Si vous omettez xargs
, find | grep
son modèle correspond-il à la liste des noms de fichiersfind
s'imprime.
Donc, à ce stade, vous pourriez tout aussi bien faire find -name stdlib.h
. Bien sûr, avec -name '*.c' -name stdlib.h
, vous n'obtiendrez aucune sortie car ces modèles ne peuvent pas correspondre, et le comportement par défaut de find est de ET les règles ensemble.
Remplacer less
à tout moment du processus pour voir quelle sortie n'importe quelle partie du pipeline produit.
Pour en savoir plus: http://mywiki.wooledge.org/BashFAQ a quelques bonnes choses.