Bash – How to recursively remove all but list of files

bashfindrmshell-script

How can I recursively remove everything in a directory EXCEPT a small list of files to preserve? For example, let's try to remove all files except ones named f2 and f5.

# Create a testing ground
mkdir -p d{1..3}
touch d{1..3}/f{1..5}

# Remove all files EXCEPT ones named f2 and f5.
find . -type f -not -name ('f2'|'f5') -type f -exec rm -f '{}' +

# Remove empty directories
find . -type d -empty -delete

Produces:

bash: syntax error near unexpected token `('

The end goal is to execute this from within a larger C userspace app, but using system() to execute a command line command seems a lot easier.

Best Answer

find . -type f -not \( -name f2 -o -name f5 \) -delete

should do it.

-delete is just like -exec rm -f '{}' + but shorter and even more efficient. Run it first without it though, to confirm it gets only the files you really do want deleted.