Sometimes, you may encounter a situation where you need to delete all files in a directory, or simply clean a directory by deleting files except some specified types (ending with a specified extension).
In this article, we will show you how to delete files in a directory except the specified file extension or type through the rm, find and globignore commands.
Before we go any further, let’s start with a brief look at an important concept in Linux – filename pattern matching, which allows us to solve the problem at hand.
Under Linux, a shell pattern is a string containing the following special characters, called wildcards or metacharacters:
* – matches 0 or more characters
? – matches any single character
[sequence] – Match any character in the sequence
[!sequence] – Match any character not in the sequence
We will explore three possible approaches here, including:
Delete files using extended pattern matching operators
The different extended pattern matching operators are listed below. These pattern lists are a list containing one or more file names separated by |:
* (pattern list) – matches 0 or more occurrences of the specified pattern
?(pattern list) – matches 0 or 1 occurrences of the specified pattern
@(pattern list) – matches 1 or more occurrences of the specified pattern
!(pattern list) – matches except one specified pattern Anything
In order to use them, you need to turn on the extglob shell option as follows:
# shopt -s extglob
1. Enter the following command to delete all files except filename in a directory
$ rm -v !("filename")
Delete except one file under Linux All files except filename1 and filename2
2. Delete all files except filename1 and filename2
$ rm -v !("filename1"|"filename2")
Delete all files except some files under Linux
3. The following example shows how to delete except some files through interactive mode All files except .zip
$ rm -i !(*.zip)
Delete all files except Zip files under Linux
4. Next, you can delete all files except .zip and .odt in a directory by the following method All files of the file, and when deleting, display the file being deleted:
$ rm -v !(*.zip|*.odt)
Delete all files except the specified file extension
Once you have executed all the required commands, you can also use the following method Turn off the extglob shell option.
$ shopt -u extglob
Use the find command under Linux to delete files
In this method, we can just use the appropriate options of the find command or use pipes with the xargs command, as shown 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 except .gz in the current directory
$ find . -type f -not -name '*.gz' -delete
find command - Delete all files except .gz
6. Using pipes and xargs, you can modify the above example as follows:
$ find . -type f -not -name '*gz' -print0 | xargs -0 -I {} rm -v {}
Use find and xargs commands to delete files
7. Let’s look at an additional example. The following command line will delete all files except .gz, .odt and .jpg in the current directory:
$ find . -type f -not \(-name '*gz' -or -name '*odt' -or -name '*.jpg' \) -delete
Delete all files except the specified extension file
Delete files through the GLOBIGNORE variable in bash
However, this last method only works with bash. The GLOBIGNORE variable stores a colon-separated list of ignored patterns (or file names) for the pathname expansion function.
To use this method, change to the directory where you want to delete the files and set the GLOBIGNORE variable like this:
$ cd test $ GLOBIGNORE=*.odt:*.iso:*.txt
In this case, all files except .odt, .iso and .txt, will be removed from The current directory is deleted.
Now, run the following command to clear this directory:
$ rm -v *
After that, close the GLOBIGNORE variable:
$ unset GLOBIGNORE
使用 bash 变量 GLOBIGNORE 删除文件
注:为了理解上面的命令行采用的标识的意思,请参考我们在每一个插图中使用的命令对应的 man 手册。