Meilleur moyen d'exécuter une commande sur chaque fichier d'une arborescence de répertoires

13

Il semble y avoir un certain nombre de façons de le faire, y compris des boucles dans le script shell, find et xargs. Laquelle de ces options est la meilleure et la plus portable?

Brian Lyttle
la source

Réponses:

13
find . -exec <command> {} \;

pour le répertoire courant comme racine de l'arborescence ou en général:

find <directory> -exec <command> {} \;
txwikinger
la source
4
sur certains systèmes, find ne dispose pas de l'option -exec, vous pouvez utiliser find. | xargs <Commande>
Hemant
4
En effet, et si vous avez besoin de filtrer par quelque chose, essayez -name "*.c"ou par exemple -type dpour les répertoires ...
La recherche peut faire des choses étonnamment complexes - vous voudrez peut-être consulter la page de manuel - unixhelp.ed.ac.uk/CGI/man-cgi?find - pour la liste complète des options.
Lucas Jones
Vous pouvez également faire attention aux noms de fichiers avec des espaces, ce qui peut casser l'approche -exec et xargs. Voir tinyurl.com/ygvgmw5
Shawn Chin
Si possible, utilisez l' find ... | xargs ...idiome, il traite les fichiers par lots, et cela sera généralement plus rapide (moins de processus lancés).
vonbrand
5

Utilisez l' -print0option pour rechercher et l' -0option pour xargssi vous avez des noms de fichiers ou de répertoires avec des espaces:

find {dir} -print0 | xargs -0r {command}

L' -print0option de recherche imprime les noms de fichiers sous NULforme de liste séparée plutôt que d'espaces séparés, tandis que l' -0option de lui xargsdemander de briser son entrée NULplutôt que d'espaces. Étant donné que NULc'est l'un des caractères qui n'est pas autorisé dans les noms de fichiers Unix, il n'y a aucun moyen de le confondre avec une partie d'un nom de fichier.

L' -roption est là pour que xargscela ne vous donne pas d'erreur si elle n'a pas d'entrée.

dhd
la source
3

Si la portabilité est un problème, je resterais à l'écart des méthodes spécifiques au shell (il y a beaucoup de gens qui utilisent beaucoup de shells différents, mais en général find et xargs sont vraiment des outils de base que personne n'oserait changer radicalement) .

L'utilisation d'arguments de base de find et xargs devrait vous donner une solution plus portable.

nc3b
la source
2

Si le regroupement des arguments est acceptable, recherchez | xargs donnera probablement de meilleures performances, car il exécutera la commande beaucoup moins de fois que find -exec. Si vous souhaitez exécuter la commande à chaque fois pour chaque fichier ou l'exécuter dans le sous-répertoire du fichier, vous devez probablement utiliser find -exec ou -execdir.

En règle générale, il est préférable de rester à l'écart des boucles spécifiques au shell; find & xargs sont suffisants pour la plupart des scénarios.

Eugen Anghel
la source
1

Assurez-vous que la version de la commande que vous utilisez n'a pas déjà d'indicateur pour une opération récursive. :)


la source
0
find [args] -print | xargs {command}

Fonctionne le mieux pour moi.

Josh K
la source
2
-1 Ne fonctionne pas pour les noms de fichiers contenant des espaces. Mieux utiliser find -print0 | xargs -0.
starblue