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?
Bash has extended globbing (first test, then remove the echo):
shopt -s extglob
echo rm -rf !(A)
shopt | grep ext
You can see if the plugin is enabled.
Commented
Nov 21, 2015 at 21:24
What about:
mv A /tmp/
rm * -rf
mv /tmp/A .
This avoids some of the "scariness" of a typo in the other commands.
Please be aware to not be in the root (/) folder when running the rm * -rf command above.
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.
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...
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.
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
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.
In addition to the earlier example of:
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
you can also do:
find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;
to avoid having to cd some/subdir
first.