Remove all directories from within a parent directory except one and its descendents
I want to remove directory B and D. But i want to keep C and all its descendent files and directories. What's the command to remove all children directories of a parent directory except one directory and its children.
Help appreciated.
Solution 1:
Using the bash shell's extended glob features (which are enabled by default in current Ubuntu installations), given
$ tree A
A
├── B
├── C
│ ├── ac1
│ └── ac2
└── D
5 directories, 0 files
you can address everything excluding C
and its contents using the glob expression A/!(C)
i.e.
$ echo A/!(C)
A/B A/D
So to remove everything except directory C
and its contents you can simply use
rm -rf A/!(C)
leaving
$ tree A
A
└── C
├── ac1
└── ac2
3 directories, 0 files
Solution 2:
What you want is this command:
find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
Demo:
# List what's inside directory we want to remove
$ ls
file1 file2 keepMe/ removeA/ removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1 file2 keepMe/
Explanation:
-
find DIRECTORY
call find command to operate upon DIRECTORY -
-mindepth 1
: work only with contents of the directory , avoid directory itself which is level 0 -
-maxdepth 1
: prevents descending into subdirectories (rm -rf
is recursive anyway, so we don't need to descend into subdirectories to remove them ) -
-type d
: search only for directories -
-not \( -name "keepMe" \)
ignore item with the name you want to keep -
-exec rm -rf {} \;
perform removal on each found item