2010-01-19 5 views
0

J'ai un tas de dirs, disons ** a, b, c0, d, Z, foo, ** et ainsi de suite.script shell pour supprimer les répertoires sélectionnés

Je veux supprimer tous les répertoires sauf dirs foo, foo2, un et b

quelqu'un peut me fournir la syntaxe pour faire cette coquille?

Merci

MISE À JOUR Je veux juste vous dire merci à vous tous pour vos réponses!

Répondre

3

Probablement le moyen le plus simple;

mkdir ../tempdir 
mv foo foo2 a b ../tempdir 
rm * 
mv ../tempdir/* . 
rmdir ../tempdir 

S'il vous plaît noter que cette opération supprime également tous les fichiers , pas seulement les répertoires.

+0

ah (c.-à supprimer tous ces articles.)! C'est tout! En fait, je veux aussi supprimer des fichiers. Merci beaucoup! – cppb

4
echo `ls -1 -d */ | egrep -v '^(foo|foo2|a|b)/$'` 

Si vous êtes satisfait de la sortie, remplacez echo avec rmdir (ou rm -r, si les répertoires contiennent encore des données).

+0

pas besoin de -1. – ghostdog74

+0

merci, j'ai essayé cela et ça fonctionne bien. – cppb

+0

Mettre en place l'exemple '$()' ou échafaudé backtick également? – Kimvais

1

Vous pouvez utiliser find sur une ligne de commande compliquée, mais le moyen le plus simple et le plus sûr est peut-être de créer un fichier qui répertorie tous les répertoires que vous souhaitez supprimer. Utilisez ensuite le fichier en entrée à rm comme ceci:

find . -maxdepth 1 -type d > dirs_to_remove 

modifier maintenant le fichier et retirez tous les répertoires que vous souhaitez garder, utilisez rm:

rm -ir $(<edited_dirs_to_remove) 

Notez le argument -i. C'est facultatif et force rm à vous demander avant de supprimer chaque fichier. Notez également la syntaxe $(<filename), qui est spécifique à bash et est équivalente à, mais moins cher que $(cat filename).

0

une façon

find . -maxdepth 1 -type d \(! -name "bar" -a ! -name "foo" -a ! -name "a" -a ! -name "b" \) -delete # to remove files as well, remove -type d 

ou essayez d'utiliser extglob

shopt -s extglob 
rm -rf !(foo|bar|a|b)/ # to delete files as well, remove the last "/" 

Et oui, cela suppose que vous ne voulez pas le reste des répertoires dans votre répertoire, sauf les 4 répertoires que vous souhaitez.

+0

!!! ATTENTION !!! Cela suppose qu'il n'y a pas de sous-répertoire sous a, b, bar et foo. Les noms des sous-répertoires ne correspondent PAS aux critères, et ils seront supprimés. –

+0

merci. L'information sur extglob est utile. – cppb

+0

Moral: N'exécutez JAMAIS une commande de suppression groupée à moins que vous ayez vérifié qu'elle fera ce que vous attendez. Dans le cas de find, supprimez simplement la commande -delete. En général, testez la commande en remplaçant "rm" par "ls" –

1

L'un des plus puissants moyens de faire ce genre de truc est en utilisant find + grep + xargs:

DONT_REMOVE='a|b|c0|d|Z|foo' 
find . -type d -print | egrep -v "^\.$DONT_REMOVE\$" | xargs rm -r 

Le seul truc fait que le modèle ici correspond uniquement à ceux que vous ne voulez pas supprimer . Le motif ci-dessus correspond uniquement aux fichiers du répertoire en cours. Vous pouvez le rendre plus ou moins permissive, par exemple:

IF_PATH_IS_IMMEDIATE_SUBDIR="^\./($DONT_REMOVE)$" 
IF_PATH_ENDS_IN="/($DONT_REMOVE)$" 
IF_PATH_CONTAINS="/($DONT_REMOVE)(/.*)?$" 

ensuite passer l'un de ces derniers dans votre egrep, e.g:

find . -type d -print | egrep -v "$IF_PATH_ENDS_IN" | xargs rm -r 

Pour inverser le choix juste enlever la -v de la egrep

+0

Vous pouvez simplifier cela en ajoutant "-maxdepth 1" à la commande find. "Trouver" ressemble beaucoup à "faire" - je n'ai jamais fini de l'apprendre. :-) –

+0

Merci. Je n'étais pas sûr si un seul niveau de sous-répertoires était suffisant, d'où les différentes options. –

+0

'find' (au moins la version GNU) a' -regex' de sorte que vous pouvez éliminer 'egrep'. Aussi, si vous faites 'find ... -print0 | egrep -z ... | xargs -0 ... 'votre commande fonctionnera avec les fichiers qui ont des espaces dans leurs noms. –

Questions connexes