7

I have a folder containing a lot of folders and different files with the following structures :

NASA
│
├── a
│   ├── doc1
│   ├── doc2
│   ├── doc3
│   ├── folder1
│   └── folder2
│
├── b
│   ├── doc1
│   ├── doc2
│   ├── doc3
│   ├── folder1
│   └── folder2
│
├── c
│   ├── doc1
│   ├── doc2
│   ├── doc3
│   ├── folder1
│   └── folder2
│
├─ x
├─ y
└─ z     

I want to delete the content of the folder (NASA/) except specified folders and files.

For example I want to keep a folder, b folder and x file.

I tried this solution :

 rm !(a/) -r NASA/

And (as explained in the answer here):

find NASA/ -type f ! -iname "x" -delete

But this is not very straight forward and I have to use a bash script.

Am I missing a more easy way ? How can I do this in a single command?

17

You can use GLOBIGNORE to set the names that will be ignored while globbing and then use * to match all other files/directories:

GLOBIGNORE='a:b:x'; rm -r *

Example:

$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
├── c
│   ├── 1
│   ├── 2
│   └── 3
├── x
├── y
└── z

/NASA$ GLOBIGNORE='a:b:x'

/NASA$ rm -r *

/NASA$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
└── x

Alternately, you can use find, from the NASA directory:

find . -maxdepth 1 ! -name '.' ! -regex '.*/\(a\|b\|x\)$' -exec rm -r {} +

Example:

/NASA$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
├── c
│   ├── 1
│   ├── 2
│   └── 3
├── x
├── y
└── z


/NASA$ find . -maxdepth 1 ! -name '.' ! -regex '.*/\(a\|b\|x\)$' -exec rm -r {} +


/NASA$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
└── x
17

You can use the extended globbing, but the exclamation mark goes before the pattern:

rm -rf NASA/!(a|b|x)

If extglob is not on, activate it first:

shopt -s extglob
  • This worked for me. – W.M. Apr 1 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.