Remove all directories from within a parent directory except one and its descendents

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.

Replay

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

One easy way would be to use trash-cli

you can install it with sudo apt-get install trash-cli

once installed you can navigate to the parent directory A with cd /A and then issue the command trash B D where B and D are the directories you want to remove (they will end up in the trash bin for the drive they are on so if you make a mistake you can recover the files)

Tested under Ubuntu 16.04 and 14.04

Simply use Bash's for loop and test to filter the desired directories and the rm -rf command to recursively delete directories, like this:

for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done

This iterates over all elements (files and directories) inside /path/to/parent/ and deletes the element recursively if its name is not equal to dir_survive. If the parent directory is the current directory, you may only write * as path.

If you are unsure and want to test which elements would get deleted first without taking any action, simply replace the rm -rf in the command above with echo and it will only output the delete candidates.

Here's an example run:

$ tree
.
├── dir1
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
├── dir2
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

9 directories, 12 files

$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done

$ tree
.
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

3 directories, 4 files

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

Category: filesystem Time: 2016-07-29 Views: 0

Related post

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development

search

Front-end development

Database

development tools

Open Platform

Javascript development

.NET development

cloud computing

server

Copyright (C) avrocks.com, All Rights Reserved.

processed in 0.184 (s). 12 q(s)