How to Delete Files with Specific Extension in Linux Command Line
You might have a situation where you want to remove multiple files that have a particular extension. This tutorial will help you do exactly that.
You use the rm command to delete files and folders in the following fashion:
rm [option] filename
It may look like that you need to know the exact file names here but that's not true.
Let me show you a couple of methods to remove multiple files based on their file extension.
Method 1: Remove files by extension using rm command
In my example, I have a bunch of gif files that end with .gif extensions.
To remove them, I can use the rm command like this:
rm *.gif
Removing files blindly like that could be risky. It's always good to first see what files will be deleted using the ls command:
ls *.gif
Here's how I delete the files with extension .gif:
$ ls
1.gif 2.gif 3.gif 4.gif a.jpg b.png c.webp
$ ls *.gif
1.gif 2.gif 3.gif 4.gif
$ rm -v *.gif
removed '1.gif'
removed '2.gif'
removed '3.gif'
removed '4.gif'
$ ls
a.jpg b.png c.webp
This can be done for any file extension, not just .gif. You may even combine multiple extensions.
$ ls
f1.txt f2.txt f3.txt f4.txt not-txt-file.pdf random.txt
$ rm -v *.txt *.pdf
removed 'f1.txt'
removed 'f2.txt'
removed 'f3.txt'
removed 'f4.txt'
removed 'not-txt-file.pdf'
$ ls
random.txt
Wondering how does it work? Wildcards!
In a nutshell, a wildcard is a special character that you use to match a particular pattern. Below are a few wildcards that are frequently used:
Wilcard | Use |
---|---|
* | Match one or more occurrence |
? | Match a single occurrence |
[] (Square brackets) | Specify a range for matching |
^ | Exclude from match |
You have used the * wildcard here which means it can match one or more occurrence of any character.
When you say *.gif
, it means any combination of letters that leads upto .gif
. In other words, it gives you all the files with the extension .gif
.
Each wildcard can be used in addition to one more wildcards. But let's not go into those details right now.
That dot between * and extension is important!
Many people commit the mistake of confusing the *.gif
with *gif
. This is not right. The dot (.) between * and extension name is crucial.
Take the scenario with the following files and look what happens when I use the regex *gif
instead of *.gif
:
$ ls
1.gif 2.gif 3.gif 4.gif definately-not-a-gif jpg-not-gif not-a-gif
$ rm -v *gif
removed '1.gif'
removed '2.gif'
removed '3.gif'
removed '4.gif'
removed 'definately-not-a-gif'
removed 'jpg-not-gif'
removed 'not-a-gif'
It also deleted files with the string gif
in it, even though it was not the file's extension, it just had gif at the end of the filename without the preceding dot.
When you remove files with wildcards or regex, please ensure that you are as precise as possible.
Method 2: Recursively delete files with a particular extension using find command
The rm command deletes only the files in the current directory. It does not delete files from the subdirectories, even with the recursive option.
To recursively delete files with a particular extension, you can combine the find command and rm command:
Here's an example where I have .gif files in the subdirectories as well.
$ ls *
file_0.gif file_z.txt not-a-gif not-a-txt
dir1:
file_1.gif file_a.txt not-a-gif not-a-txt
dir2:
file_2.gif file_b.txt not-a-gif not-a-txt
dir3:
file_3.gif file_c.txt not-a-gif not-a-txt
dir4:
file_4.gif file_d.txt not-a-gif not-a-txt
To delete the files, you can use the find and exec commands like this:
find . -type f -name "*.gif" -exec rm -v {} \;
Here's the output when I ran the command:
$ find . -type f -name "*.gif" -exec rm -v {} \;
removed './dir1/file_1.gif'
removed './dir3/file_3.gif'
removed './dir2/file_2.gif'
removed './file_0.gif'
removed './dir4/file_4.gif
Let's break it down.
- The period after "find" means to search in current directory
- The "-name" flag specifies the name of the file, where we can use regex
- The "-exec" flag is used to execute a bash command on the result of the find command
- The "{}" braces acts as the placeholder for the result of matched file(s), so "rm -v {}" will delete the files that find command found.
- Finally, the semicolon ends the command executed by your shell (the command after exec) and the backslash '\' is used so that the semicolon is escaped properly. You shouldn't worry about this.
You can learn more examples of the find command in the tutorial below.
Advanced Bonus Tip: Use find command to work on files with multiple extensions
The command shown above doesn't cover finding files with multiple extensions, something like "rm *.gif *.txt"
To achieve that, you can use the -o
argument that means 'logical OR operator'. But we also have to use the backslash '\' to escape the parentheses
$ ls *
file_0.gif file_z.txt not-a-gif not-a-txt
dir1:
file_1.gif file_a.txt not-a-gif not-a-txt
dir2:
file_2.gif file_b.txt not-a-gif not-a-txt
dir3:
file_3.gif file_c.txt not-a-gif not-a-txt
dir4:
file_4.gif file_d.txt not-a-gif not-a-txt
$ find . \( -name "*.gif" -o -name "*.txt" \) -exec rm -v {} \;
removed './dir1/file_1.gif'
removed './dir1/file_a.txt'
removed './dir3/file_3.gif'
removed './dir3/file_c.txt'
removed './dir2/file_2.gif'
removed './dir2/file_b.txt'
removed './file_0.gif'
removed './file_z.txt'
removed './dir4/file_d.txt'
removed './dir4/file_4.gif'
Here, you can see that all the files with a 'txt' extension and files with a 'gif' extension are removed, recursively.
I know that you will feel like using the find command separately for each file extension type would be easier and you are not wrong there.
Conclusion
This article covered removing files with a particular extension. We also looked at recursively finding and removing these files.
"With great power, comes great responsibility", remember this when you use wildcards and regex. One mistype and important files might get deleted unintentionally.