web-dev-qa-db-fra.com

Comment supprimer des répertoires basés sur la sortie `find`?

J'émets la commande suivante pour trouver les répertoires .svn:

find . -name ".svn"

Cela me donne les résultats suivants:

./toto/.svn
./toto/titi/.svn
./toto/tata/.svn

Comment pourrais-je traiter toutes ces lignes avec rm -fr pour supprimer les répertoires et leur contenu?

169
Arnaud

Find peut exécuter des arguments avec le -exec option pour chaque correspondance trouvée. Il s'agit d'un mécanisme recommandé car vous pouvez gérer correctement les chemins contenant des espaces/retours à la ligne et d'autres caractères. Vous devrez supprimer le contenu du répertoire avant de pouvoir supprimer le répertoire lui-même, utilisez donc -r avec la commande rm pour y parvenir.

Pour votre exemple, vous pouvez émettre:

find . -name ".svn" -exec rm -r "{}" \;

Vous pouvez également dire à find de simplement trouver les répertoires nommés .svn en ajoutant un -type d vérifier:

find . -name ".svn" -type d -exec rm -r "{}" \;

Avertissement Utilisez rm -r avec précaution, il supprime le dossier et tout son contenu.

Si vous souhaitez supprimer uniquement les répertoires vides ainsi que les répertoires qui ne contiennent que des répertoires vides, find peut le faire lui-même avec -delete et -empty:

find . -name ".svn" -type d -empty -delete
213
Drav Sloan

Voici un portable encore plus rapide que le moyen de réponse accepté.

Utilisant un + au lieu d'un point-virgule comme terminateur de commande find optimise l'utilisation du processeur. Cela peut être important si vous avez beaucoup de .svn sous-répertoires:

find . -name .svn -type d -exec rm -rf {} +

Notez également que vous ne1 besoin de citer les accolades ici.

1 Sauf si vous utilisez le shell fish (cela a peut-être été corrigé depuis que j'ai écrit cette réponse).

76
jlliagre

Supposons que vous utilisez gnu find , vous pouvez utiliser le -delete option:

find . -name test -delete

ce qui est plus facile à retenir.

29
Chun Yang

Sur mon ordinateur lorsque j'utilise:

find . \( -name dirname -type d \) -exec rm -r '{}' ';'

Les répertoires sont supprimés mais j'obtiens l'erreur:

find: ‘./dirname’: No such file or directory

pour chaque répertoire.

Mes répertoires ne sont pas vides, donc l'option -delete ne fonctionnera pas pour moi. J'ai trouvé la raison de ce comportement ici :

  1. find prend (pas nécessairement) la première entrée du répertoire ./. ce serait par exemple dir.1 /
  2. il le compare au modèle 'dir.?'. cela correspond-il? Oui.
  3. find exécute "rm -r dir.1".
  4. find essaie d'entrer dir.1/pour trouver le modèle dans le répertoire. il ne sait rien de la commande exec.
  5. il ne trouve plus dir.1 /. retourne ENOENT (regardez la sortie de strace)

Je l'ai utilisé à la place pour contourner:

rm -r `find . -name dirname -type d`

Gardez à l'esprit que find essaiera toujours de récupérer dans les répertoires nommés dirname, ce qui n'est pas vraiment nécessaire et prendra un certain temps supplémentaire. Selon la structure de votre répertoire, vous pourrez peut-être contourner ce problème avec le --depth option de recherche. De plus, si vous avez une structure de répertoires comme dirname/foo/dirname, vous obtiendrez des erreurs "No such file or directory" de rm. Pour supprimer les erreurs, vous pouvez rediriger stderr vers/dev/null ou utiliser le -f (forcer) le drapeau avec rm.

13
Samuel

Un moyen plus rapide de le faire est:

find . -name ".svn" -type d -Prune -exec rm -rf '{}' '+'

Si vous avez ".svn" dans un autre ".svn".

12
Chang Yu-heng

Solution spécifique à Bash:

shopt -s globstar
rm -r **/.svn
shopt -u globstar #optional. this will disable globstar expansion
5
rush

J'ai trouvé que le -delete l'action fonctionne bien avec le -path test. Par exemple, ce qui suit devrait fonctionner sur le problème des affiches originales:

find . -path '*/.svn*' -delete
4
Magnus