3 Ways to Delete All Files in a Directory Except One or Few Files with Extensions

In Linux, a shell pattern is a string that consists of the following special characters, which are referred to as wildcards or metacharacters:

* – matches zero or more characters

? – matches any single character

[seq] – matches any character in seq

[!seq] – matches any character not in seq

 

There are three possible methods we shall explore here, and these include:

 

Delete Files Using Extended Pattern Matching Operators

 

The different extended pattern matching operators are listed below, where pattern-list is a list containing one or more filenames, separated using the | character:

*(pattern-list) – matches zero or more occurrences of the specified patterns

?(pattern-list) – matches zero or one occurrence of the specified patterns

+(pattern-list) – matches one or more occurrences of the specified patterns

@(pattern-list) – matches one of the specified patterns

!(pattern-list) – matches anything except one of the given patterns

 

To use them, enable the extglob shell option as follows:

# shopt -s extglob

 

1. To delete all files in a directory except filename, type the command below:

$ rm -v !("filename")

 

2. To delete all files with the exception of filename1 and filename2:

$ rm -v !("filename1"|"filename2") 

 

3. The example below shows how to remove all files other than all .zip files interactively:

$ rm -i !(*.zip)

 

4. Next, you can delete all files in a directory apart from all .zip and .odt files as follows, while displaying what is being done:

$ rm -v !(*.zip|*.odt)

 

Once you have all the required commands, turn off the extglob shell option like so:

$ shopt -u extglob

 

Delete Files Using Linux find Command

 

Under this method, we can use find command exclusively with appropriate options or in conjunction with xargs command by employing a pipeline as in the forms below:

$ find /directory/ -type f -not -name 'PATTERN' -delete
$ find /directory/ -type f -not -name 'PATTERN' -print0 | xargs -0 -I {} rm {}
$ find /directory/ -type f -not -name 'PATTERN' -print0 | xargs -0 -I {} rm [options] {}

 

5. The following command will delete all files apart from .gz files in the current directory:

$ find . -type f -not -name '*.gz'-delete

 

6. Using a pipeline and xargs, you can modify the case above as follows:

$ find . -type f -not -name '*gz' -print0 | xargs -0  -I {} rm -v {}

 

7. Let us look at one additional example, the command below will wipe out all files excluding .gz, .odt, and  .jpg files in the current directory:

$ find . -type f -not \(-name '*gz' -or -name '*odt' -or -name '*.jpg' \) -delete

 

Delete Files Using Bash GLOBIGNORE Variable

 

This last approach however, only works with bash. Here, the GLOBIGNORE variable stores a colon-separated pattern-list (filenames) to be ignored by pathname expansion.

 

To employ this method, move into the directory that you wish to clean up, then set the GLOBIGNORE variable as follows:

$ cd test
$ GLOBIGNORE=*.odt:*.iso:*.txt

 

In this instance, all files other than .odt, .iso, and .txt files with be removed from the current directory.

 

Now run the command to clean up the directory:

$ rm -v *

 

Afterwards, turn off GLOBIGNORE variable:

$ unset GLOBIGNORE

 

Note: To understand the meaning of the flags employed in the commands above, refer to the man pages of each command we have used in the various illustrations.

 

Was this answer helpful? 0 Users Found This Useful (0 Votes)