web-dev-qa-db-fra.com

Comment supprimer récursivement des répertoires avec des caractères génériques?

Je travaille via SSH sur une édition WD My Book World. Fondamentalement, je voudrais commencer à un niveau de répertoire particulier et supprimer récursivement tous les sous-répertoires correspondant à .Apple*. Comment pourrais-je m'y prendre?

J'ai essayé

rm -rf .Apple* et rm -fR .Apple*

ni les répertoires supprimés correspondant à ce nom dans les sous-répertoires.

55
codedog

find est très utile pour effectuer sélectivement des actions sur une arborescence entière.

find . -type f -name ".Apple*" -delete

Ici le -type f s'assure que c'est un fichier, pas un répertoire, et peut ne pas être exactement ce que vous voulez car il sautera également les liens symboliques, les sockets et d'autres choses. Vous pouvez utiliser ! -type d, ce qui signifie littéralement pas répertoires, mais vous pouvez également supprimer des caractères et bloquer des périphériques. Je suggère de regarder le -type prédicat sur la page de manuel pour find.

Pour le faire strictement avec un caractère générique, vous avez besoin d'un support Shell avancé. Bash v4 a l'option globstar , qui vous permet de faire correspondre de manière récursive les sous-répertoires en utilisant **. zsh et ksh prennent également en charge ce modèle. En utilisant cela, vous pouvez faire rm -rf **/.Apple*. Ce n'est pas standard POSIX, et pas très portable, donc j'éviterais de l'utiliser dans un script, mais pour une action Shell unique et interactive, ça va.

76
Shawn J. Goff

J'ai rencontré des problèmes avec find avec -delete en raison du comportement intentionnel de find (c'est-à-dire refusant de supprimer si le chemin commence par ./, ce qu'ils font dans mon cas) comme indiqué dans sa page de manuel:

 -delete

Supprimez les fichiers et/ou répertoires trouvés. Retourne toujours vrai. Cela s'exécute à partir du répertoire de travail actuel au fur et à mesure que find revient dans l'arborescence. Il n'essaiera pas de supprimer un nom de fichier avec un caractère "/" dans son chemin par rapport à "." pour des raisons de sécurité.
Le traitement de la traversée en profondeur d'abord est impliqué par cette option.
Les liens symboliques suivants ne sont pas compatibles avec cette option.

Au lieu de cela, je pouvais juste faire

find . -type d -name 'received_*_output' -exec rm -r {} +

Pour votre cas, il semble que citer le glob (astérisque, *) était la solution, mais je voulais fournir ma réponse au cas où quelqu'un d'autre aurait le même problème.

REMARQUE: Auparavant, ma réponse était de faire ce qui suit, mais @Wildcard a souligné les failles de sécurité dans ce cas dans les commentaires.

find . -type d -name 'received_*_output' | xargs rm -r
17
Pat

Ce qui est possible, c'est qu'il n'y a rien de mal avec votre commande rm/find, mais que l'utilisateur avec lequel vous êtes connecté n'a pas réellement les autorisations de suppression. Utilisation ls -l pour lister les choses avec leurs autorisations, et vous pouvez identifier qui vous êtes avec les commandes id et groups (l'une ou l'autre devrait être disponible). Si vous êtes le "mauvais utilisateur" pour ce faire, vous devrez soit modifier les autorisations/propriété des fichiers, soit basculer vers un autre utilisateur.

0
froztbyte

Essayer:

shopt -s dotglob           # using Bash
printf '%s\n' ./.Apple*    # test
#rm -rf ./.Apple*    
0
jan