Ubuntu – Excluding certain files and directories when deleting files

bashcommand linermscripts

My top-level directory is data. data includes several directories and these directories have sub-directories. I need to remove all files and directories inside data/ except several files in some directories.

For example, data includes the directories 100 and 101. I just want to keep a.txt and b.txt files in 100/ and c.txt and d.txt files in 101/ while removing all other files and directories in 100 and 101.

Example:

.
├── 100
│   ├── a.txt
│   ├── b.txt
│   ├── c.txt
│   └── d.txt
└── 101
    ├── a.txt
    ├── b.txt
    ├── c.txt
    └── d.txt

I use rm -rf !(a.txt|b.txt) command but I can't apply this command for each directory automatically.

Best Answer

As you already found out you can use the extglob feature which is enabled with:

shopt -s extglob

This allows to exclude matches so that you can do things like:

rm 100/!([ab].txt) 101/!([cd].txt)

It's a good idea to test it with echo first. This example will match anything inside 100/ which is not a.txt or b.txt and anything inside 101/ which is not c.txt or d.txt. If the same rules for 100/ apply to 102/ as well you can do e.g.:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)