Delete all files except SNUB.*

Sometimes, you might find yourself in a funny situation where you need to delete or clean up all files in a directory, except those with a specific file name or type.
Using commands or scripts with precise patterns and conditions can help you efficiently manage files while preserving the ones you need.

For example, you could use shell commands or scripts to identify and exclude certain files based on their names, extensions, or modification dates, ensuring that only the desired files remain untouched.

There are several ways to do that —We are going to be using find and a loop:

Here’s an example of how you might achieve this in a Unix-like system:



Using find and a loop


1. Navigate to your directory:

$ cd /path/to/your/directory


2. Create random files::

$ touch SNUB{00..09}.txt

$ touch SNUB{00..09}.jpg


3. Run either of the following commands:

$ find . -type f! —name 'SNUB06.txt' -exec rm {} +

or

$ find . -type f! —name '*.jpg' -exec rm {} +



Explanation:

touch : command used to create empty files or update their timestamps.
{00..09}SNUB.txt : brace expansion to generate the sequence of numbers from 00 to 09 and appends SNUB.txt to each number, creating filenames like SNUB00.txt, SNUB01.txt, etc.
find . : finds all files in the current directory and its subdirectories.
f! -name : excludes file 'SNUB.txt' from the results.
-exec: command to be executed, which in this case is rm (remove).
rm: command rm (remove).
{} : placeholder for the current file path found by find. Each file found by find will be replaced by {} when the command is executed.
+: this signifies that find should build the command line by appending each found file to the rm command, and then execute it once.


This method ensures that either SNUB06. txt or all .jpg files are preserved, and all other files are deleted —this is more efficient than executing the rm command separately for each file.

See our post on comparing: -exec command {} ; vs -exec command {} +;


Using SHELL built-in shopt

PS: extended globbing in zsh (Z shell) is enabled by default.

Another simple and efficient method, assuming you are working within a single directory and not recursively, is to use shopt with the -extglob option:

1. Enable extended globbing:

$ shopt -s extglob


2. Delete all files except SNUB. txt:

$ rm -v ! ('SNUB06.txt')


To delete all files except SNUNB1.txt and SNUB2.txt:

$ rm -v !("SNUNB01.txt"|"SNUNB02.txt") 


3. Disable extended globbing (optional but recommended):

$ shopt -u extglob



Explanation:

-s extglob : enables extended pattern matching.
rm -v ! ('SNUB.txt') : deletes all files except SNUB. txt in the current directory. -v : option makes rm verbose; it will print out each file it deletes.
! : pattern syntax matches anything except the pattern specified.
shopt -u extglob disables extended pattern matching.




Both methods are effective and depend on your specific use case and directory structure. Choosing between them often comes down to factors like the complexity of your file management needs, the frequency of the task, and the specific requirements of your environment. Whether using find with a loop or other file manipulation techniques, it’s essential to test and verify your approach; ensuring it performs as expected and prevents unintended data loss.