Exécuter des commandes sur plusieurs fichiers : find -exec vs find xargs
Aller à la navigation
Aller à la recherche
find -exec
find \;
find . [args] -exec [cmd] {} \; find . -name \*.html -type f -exec grep -Hn 'pattern' {} \;
{}
contiendra le résultat trouvé par find\;
signifie que pour chaque résultat trouvé par find, la commande (grep dans l'exemple) sera exécuté une fois sur le résultat trouvé- Donc si find trouve 4000 fichiers, la commande (grep ici) sera exécutée 4000 fois.
find \+
find . [args] -exec [cmd] {} \+ find . -name \*.html -type f -exec grep -Hn 'pattern' {} \+
{}
contiendra le résultat trouvé par find\+
tous les résultats trouvés par find sont mergés et la commande (grep ici) n'est exécutée qu'une seule fois avec tous les résultats de find.- Inconvénient possible : si find trouve beaucoup de résultat, vous allez finir par atteindre ARG_LIMIT
find | xargs
xargs avec -n1
find .[args] -print0 | xargs -0 -n1 [cmd] find . -name \*.html -type f -print0 | xargs -0 -n1 grep -Hn 'pattern'
-print0
spécifie à find qu'il doit retourner les résultats à la sortie standard, séparés par le caractère ASCII nul\000
-0
spécifie à xargs que l'entrée qu'il reçoit est séparé par le caractère ASCII nul\000
-n1
demande à xargs d’exécuter la commande avec un seul argument à la fois (dans le cas présent, avec un seul fichier trouvé par find). Cela est similaire au\;
de-exec
. La commande est donc exécutée autant de fois qu'il y a de fichier trouvé par find.- On peut modifier 1 par n'importe quelle valeur
xargs sans -n
find . [args] -print0 | xargs -0 [cmd] find . -name \*.html -type f -print0 | xargs -0 grep -Hn 'pattern'
-print0
spécifie à find qu'il doit retourner les résultats à la sortie standard, séparés par le caractère ASCII nul\000
-0
spécifie à xargs que l'entrée qu'il reçoit est séparé par le caractère ASCII nul\000
- Quand on ne spécifie pas
-nINT
, xargs utilise le défaut-n5000
. Cela signifie donc que la commande est exécutée avec 5000 arguments maximums, donc dans le cas présent, avec 5000 fichiers à la fois (puis la commande est exécutée une seconde fois avec les 5000 fichiers suivants, etc). Cela est similaire avec le+;
de-exec
, néanmoins sans risque de dépasser ARG_LIMIT, ni une limite arbitraire fixée par la commande que vous exécutez.
caractère ASCII nul \000
Le caractère ASCII nul \000
est une bonne manière de gérer les fichiers contenants des espaces
performances
Globalement, xargs -n1
est légèrement plus rapide que \;
, et xargs -n5000
a une vitesse similaire à \+
Notez que xargs
peut se paralléliser avec -PINT
(généralement -P4 ou -P8 selon le nombre de cœur de votre processeur), ce qui en augmentera les performances que ce soit avec -n1 ou sans.
Rappelez vous que l'intérêt de paralléliser une commande traitant des fichiers n'augmentera les performances que si vous devez appliquer une commande à un nombre important de petits fichiers. Si vous traitez de gros fichiers, la vitesse de votre disque deviendra le facteur limitant et vous perdrez très vite les bénéfices de la parallélisation.
Différence à noter
find -exec
retourne l'exit-code de find et pas celui de la sous-commande.find | xargs
retourne l'exit-code de la sous-commande.