Supprimer tous les sous-répertoires sauf un


10

Supposons que sous le répertoire actuel, il y ait plusieurs sous-répertoires, et l'un s'appelle A.

Comment supprimer tous les sous-répertoires sauf A avec Bash?

Réponses:


23

Bash a étendu le globbing (premier test, puis supprimez l'écho):

shopt -s extglob
echo rm -rf !(A)

(avant d'oublier - vous pourriez désactiver la complétion de l'historique du style CSH, dans Bash3 il y a un bug en ignorant! (. set + H

+1 Bash si plein de surprises! Parfois, ils sont sympas comme celui-ci.
Aleksandr Levchuk

Wauw très sympa en effet! Fonctionne comme prévu. Avec shopt | grep extVous pouvez voir si le plugin est activé.
danger89

14
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

10

Qu'en est-il de:

mv A /tmp/
rm * -rf
mv /tmp/A .

Cela évite une partie de la "peur" d'une faute de frappe dans les autres commandes.


1
+1 pour avoir fait le bon choix au lieu d'espérer que les outils sont suffisamment intelligents. encore, une nuit, alors que j'apprenais Linux, j'ai copié le noyau dans / tmp avant de faire ma première recompilation. il n'a pas réussi, mais a effacé l'ancien, alors j'ai dit 'pas de sueur, j'ai une copie' seulement pour constater qu'une tâche cron de minuit l'avait effacé avec chaque fichier de plus d'une semaine dans / tmp! j'ai dû recompiler à nouveau et cette fois, faites-le bien, ou pas de redémarrage pour moi!
Javier

meilleure réponse publiée :)
warren

3

Quelque chose comme

find . -type d -not -name A -exec rm -ir {} \;

devrait faire.

Éditer

Ça devrait vraiment être

find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;

pour éviter findde se reproduire en dessous de A.


3
Mais, cela supprimerait également tous les sous-répertoires sous A comme A / foo et A / bar, mais préserverait A / A.
TCampbell

Cool! Les questions et les réponses sont migrées de SO vers SF ... mais ma modification ci-dessus a été perdue ...
agnul

Il devrait être préférable d'échanger maxdepth et de taper des arguments comme ceci: find. -maxdepth 1 -type d -not -name A -exec rm -ir {} \;
Spawnrider

1

Je le fais habituellement en élaborant une commande ls qui le fait bien en premier. je ne suis pas sur une machine unix, mais quelque chose comme:

ls -lda "[^ A]"

Une fois que vous avez bien compris, dirigez-le vers une commande

ls -lda "[^ A]" | xargs rm -rf

N'hésitez pas à modifier ci-dessus si j'ai une mauvaise expression régulière ...



1

Si vous voulez être plus flexible mais manuel, vous pouvez le faire:

ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r

De cette façon, vous pouvez faire du munging général.


1

Voici une façon. Soyez prudent avec ce genre de chose, cependant, il est si puissant qu'il ne peut être utilisé que pour le bien ou le mal ...

trouver * -type d | grep -v "^ A" | xargs rm -rf

1

N'utilisez pas find car certaines personnes l'ont montré avec -exec et rm sans passer par -print0 pour trouver et -0 pour xargs. Il se confondra sur les noms de fichiers avec des espaces ou des retours à la ligne:

$ mkdir 'foo foo'
$ mkdir foo$'\n'foo 
$ find . -type d -exec rm -ir {} \;
rm: cannot remove directory `.'
rm: remove directory `./foo\nfoo'? y
find: `./foo\nfoo': No such file or directory
rm: remove directory `./foo foo'? y
find: `./foo foo': No such file or directory

Utilisez plutôt find -print0 avec xargs -0, '-exec command {} +' ou -delete si votre recherche le prend en charge.



1

En plus de l'exemple précédent de:

find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

vous pouvez aussi faire:

find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;

pour éviter d'avoir à le faire d' cd some/subdirabord.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.