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
xargsest suffisamment intelligent pour ne transmettre que le nombre d'arguments rmqu'il peut accepter. Ainsi, si vous aviez un million de fichiers, il pourrait s'exécuter rm1 000 000/65 000 fois (si votre shell pouvait accepter 65 002 arguments sur la ligne de commande {65k fichiers + 1 pour rm + 1 pour -fr}).
Comme des 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 -execformulaires appellent tous les deux rmpour chaque dossier en cours de suppression, donc si vous aviez 1 000 000 de dossiers, rmils seraient appelés 1 000 000 fois. C'est certainement loin d'être idéal. Les nouvelles implémentations de rmvous permettent de conclure la commande avec un +indicateur qui rmacceptera autant d'arguments que possible:
find . -name .svn -exec rm -rf {} +
La dernière version de find / xargs utilise print0, ce qui permet à find de générer une sortie qui l'utilise \0comme terminateur plutôt que comme nouvelle ligne. Puisque les systèmes POSIX autorisent n'importe quel caractère sauf \0dans le nom de fichier, c'est vraiment le moyen le plus sûr de s'assurer que les arguments sont correctement passés à rmou à l'application en cours d'exécution.
De plus, il y a un -execdirqui s'exécutera à rmpartir du répertoire dans lequel le fichier a été trouvé, plutôt que dans le répertoire de base et un -depthqui démarrera en premier.