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.