Suppose under the current directory, there are multiple sub-directories, and one is called A.

How to delete all sub-directories except A with Bash?

link|improve this question
feedback

9 Answers

Bash has extended globbing (first test, then remove the echo):

shopt -s extglob
echo rm -rf !(A)
link|improve this answer
(before I forget - you might disable CSH style history completion, in Bash3 there's a bug while ignoring !(. set +H – TheBonsai Jun 4 '09 at 19:38
+1 Bash if full of surprises! Sometimes they are nice like this one. – Aleksandr Levchuk Nov 16 '10 at 1:46
feedback
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
link|improve this answer
2  
wtf community wiki? – dotjoe Jun 4 '09 at 21:31
feedback

Something like

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

should do.

edit

It should really be

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

to prevent find from recursing below A.

link|improve this answer
3  
But, this would also remove any sub-directories below A like A/foo and A/bar, but would preserve A/A. – TCampbell Jun 4 '09 at 19:30
Cool! Questions and answert get migrated from SO to SF... but my edit above was lost... – agnul Jun 4 '09 at 19:47
feedback

What about:

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

This avoids some of the "scariness" of a typo in the other commands.

link|improve this answer
1  
+1 for doing the sane thing instead of hoping the tools are smart enough. still, one night, when i was just learning Linux, i copied the kernel to /tmp before doing my first recompile. it didn't succeed, but erased the old one, so i said 'no sweat, i have a copy' only to find that a midnight cron task had erased it with every file more than a week old in /tmp! i had to recompile again and this time do it right, or no reboot for me! – Javier Jun 4 '09 at 21:16
best answer posted :) – warren Nov 16 '10 at 2:59
feedback

i usually do this by working up an ls command that gets it right first. i'm not at a unix machine, but something like:

ls -lda "[^A]"

Once you get it right, pipe it to a command

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

Feel free to edit above if I've got my regular expression wrong...

link|improve this answer
You shouldn't parse ls: mywiki.wooledge.org/ParsingLs – Dennis Williamson Jun 4 '09 at 22:41
feedback

If you want to be more flexible but manual you can do:

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

That way you can do general munging.

link|improve this answer
feedback

Here's one way. Be careful with this sort of thing, though, it's so powerful that it can only be used for good or evil...

find * -type d | grep -v "^A" | xargs rm -rf
link|improve this answer
feedback

Don't use find as some people have shown with -exec and rm without passing -print0 to find and -0 to xargs. It will get confused on file names with spaces or newlines:

$ 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

Instead use find -print0 with xargs -0 , '-exec command {} +', or -delete if your find supports it.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown