Pas besoin de pipes, xargs, exec ou quoi que ce soit :
find . -name .svn -delete
Modifier : Je plaisante, évidemment -delete
appelle le unlinkat()
sous le capot, il se comporte donc comme unlink
ou rmdir
et refusera d'opérer sur les répertoires contenant des fichiers.
Ce que vous avez écrit envoie une liste de noms de fichiers (et de chemins) séparés par une nouvelle ligne à rm
, mais rm ne sait pas quoi faire avec cette entrée. Il n'attend que des paramètres de ligne de commande.
xargs
prend des entrées, généralement séparées par des retours à la ligne, et les place sur la ligne de commande, donc l'ajout de xargs fait fonctionner ce que vous aviez :
find . -name .svn | xargs rm -fr
xargs
est suffisamment intelligent pour ne transmettre qu'autant d'arguments à rm
comme il peut accepter. Ainsi, si vous aviez un million de fichiers, il pourrait exécuter rm
1 000 000/65 000 fois (si votre shell pouvait accepter 65 002 arguments sur la ligne de commande {65k files + 1 for rm + 1 for -fr}).
Comme les personnes l'ont habilement souligné, les éléments suivants fonctionnent également :
find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf
Les deux premiers -exec
les deux formes appellent rm
pour chaque dossier supprimé, donc si vous aviez 1 000 000 dossiers, rm
serait invoqué 1 000 000 fois. C'est certainement loin d'être idéal. Nouvelles implémentations de rm
permet de conclure la commande par un +
indiquant que rm
acceptera autant d'arguments que possible :
find . -name .svn -exec rm -rf {} +
La dernière version de find/xargs utilise print0, ce qui fait que find génère une sortie qui utilise \0
comme un terminateur plutôt qu'un retour à la ligne. Puisque les systèmes POSIX autorisent n'importe quel caractère sauf \0
dans le nom du fichier, c'est vraiment le moyen le plus sûr de s'assurer que les arguments sont correctement passés à rm
ou l'application en cours d'exécution.
De plus, il y a un -execdir
qui exécutera rm
depuis le répertoire dans lequel le fichier a été trouvé, plutôt que dans le répertoire de base et un -depth
qui commencera la profondeur en premier.
Essayez ceci :
find . -name .svn -exec rm -rf '{}' \;
Avant d'exécuter une commande comme celle-ci, j'aime souvent exécuter celle-ci :
find . -name .svn -exec ls '{}' \;