How can I recursively delete all files of a specific extension in the current directory?
How do I safely delete all files with a specific extension (e.g. .bak ) from current directory and all subfolders using one command-line? Simply, I’m afraid to use rm since I used it wrong once and now I need advice.
8 Answers 8
You don’t even need to use rm in this case if you are afraid. Use find :
find . -name "*.bak" -type f -delete
But use it with precaution. Run first:
to see exactly which files you will remove.
Also, make sure that -delete is the last argument in your command. If you put it before the -name *.bak argument , it will delete everything.
See man find and man rm for more info and see also this related question on SE:
With default settings rm *.bak will only delete all files ending with .bak in the current directory. TO also do things in subdirectories you either needed to fiddle with globs, use the -r option or use the find example.
@Hennes Be careful with rm -r *.bak ! It also removes directories ending in .bak with all their content.
Make sure that -delete is the last argument in your command. If you put it before the -name *.bak argument, it will delete everything.
First run the command shopt -s globstar . You can run that on the command line, and it’ll have effect only in that shell window. You can put it in your .bashrc , and then all newly started shells will pick it up. The effect of that command is to make **/ match files in the current directory and its subdirectories recursively (by default, **/ means the same thing as */ : only in the immediate subdirectories). Then:
(or gvfs-trash **/*.bak or what have you).
@Gilles’SO-stopbeingevil’ but there were matching files in sub directories. I’ve used find . -name ‘*.md’ -type f -delete afterwards and deleted them successfully
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f
Welcome to askubuntu! While this is a perfectly valid answer I don’t think there’s any advantage in using this instead of the -delete flag of find . More information can be found in the GNU manuals entry for deleting files with find.
This is not just an alternative but an example how other commands can be combined together with the pipe ‘|’. +1
Deleting files is for me not something you should use rm for. Here is an alternative:
sudo apt-get install gvfs # install a tool that allows you to put stuff in the trash alias "trash"="gvfs-trash" # you can also put this in .bash_aliases or simply use the command without alias trash *.bak # trash the files (thus moving them to the trash bin)
As Flimm states in the comments:
The package trash-cli does the same thing as gvfs-trash without the dependency on gvfs.
sudo apt-get install trash-cli
You don’t need to make an alias for this, because the trash-cli package provides a command trash , which does what we want.
As Eliah Kagan makes clear in extensive comments, you can also make this recursive using find . In that case you can’t use an alias, so the commands below assume you have installed trash-cli . I summarise Eliah’s comments:
This command finds and displays all .bak files and symlinks anywhere in the current directory or its subdirectories or below.
To delete them, append an -exec with the trash command:
find . -name '*.bak' -xtype f -exec trash <> +
-xtype f selects files and symlinks to files, but not folders. To delete .bak folders too, remove that part, and use -execdir , which avoids cannot trash non-existent errors for .bak files inside .bak directories:
find . -name '*.bak' -execdir trash <> +
How to Find and Delete Files in Linux
This tutorial explains how to combine the Linux find command with others to search and delete the files with a single command execution.
After reading this tutorial, you will know how to simplify the task of removing the files in Linux using different techniques. This tutorial is optimized for both new and experienced users, going straight to the practical point and explaining every aspect. I encourage you to practice all examples given in order to incorporate this knowledge. Just be careful with the content you delete.
This article includes the screenshots of every step, making it easy for all the Linux users to apply them.
Finding and Deleting Files in Linux
This section explains the different techniques to find the files and delete them on the fly with a single command or with commands combination.
To begin, let’s see what is in the home directory by using the ls (List) command.
As you can see in the previous figure, there are several files and directories. Among them, we can see the 1.txt, 2.txt and 3.txt.
We can use the find command followed by the file type, the file name, and the –delete option.
But in the following example, we will not remove a specific file but all the files with the “.txt” extension.
- find: The find command is evidently used to search the files.
- . (Dot): The dot after the find command specifies that the operation must be done within the current directory. Our case is in the home directory, therefore this dot is equal to /home/user.
- -type f: This option specifies what files we want to find. In case you want to search the directories, replace the f with a d.
- -name: This is the option to specify the file/directory target. This option must be typed before the file/directory name to define it.
- “*.txt”: In this particular case, we search all the “.txt” files that we specify by typing “*.txt”.
- -delete: This option instructs the find command to delete the found files.
As you can see in the previous screenshot, after executing the ls command again, the txt files don’t show up. They were removed by the previously executed command.
Of course, you can find and delete the specific files as shown in the following figure where file3 is found and removed.
As explained in the previous command and options list, if you want to remove a directory rather than a file, you need to replace the f with a d after the -type option as shown in the following image:
Let’s assume that you want to delete many files whose first part of their names are the same. In the following screenshot, you can see the file1, file2 and file3.
If you want to remove all the “fileX” files, you only need to replace the part of the file names without coincidence with the wildcard (*) as shown in the following example:
All previous examples explained how to delete the files using the -delete option. This section explains how to get the same result using the –exec command.
The first part of the following command was already explained previously. The incorporated -exec command is used to apply an action based on the result of the previous command.
- -exec: Instructs to execute a posterior command after the first command (find) execution.
- rm -rf: This command is used to force the removal of files and directories matching the given names.
- “<>”: This is the find command placeholder, which means that it takes the file or directory names given to the find command to run the given command (After –exec) on them. In the previous example, rm -rf is applied to the <> placeholder which represents the “log”
- “\;”: The back slash and the semicolon closes or finishes the –exec
Now, let’s see a new scenario using the ls command again. As you can see, there are different “.txt” files.
In this case, we will replace the –delete option with the -exec rm again to delete all the “.txt” files as we did in the second example of this document but using a different technique.
You can see the command in the third line of the following figure. The previous ls command shows the existing files before executing find, and the second ls shows the result with all the “.txt” files deleted.
Now, let’s create a new scenario which you can see in the following example. This scenario includes several “.txt” and “.c files”.
Let’s assume that you want to remove both .txt and .c files at once using the -delete option instead of the –exec option. As you can see in the following image, name files are between the \( and \). Before the second file name, we have the -o option followed by the -name and the second file name (or condition in this case, since we are deleting all the “.txt” files). You can add the -o -name many times as you need, but remember that the first –name is not preceded by the –o option.
As you can see, both .txt and .c files were successfully removed.
Now, let’s combine the find command with the xargs command (explained at the end of this tutorial).
In the following example, we delete all the “.txt” files using xargs, where –I is the placeholder and between % we execute the command.
As you can see, after the second ls execution, all .c and .txt files were removed.
The syntax to delete many files is easier with xargs. In the following command, both .c and .txt files are removed.
Finally, let’s assume that you want to remove the files by date and not by name or extension. In this case, the find command can identify the mtime (creation or modification file dates) of the files and directories.
In the following image, you can see the dir2 directory that contains 4 files: file1, file2, file3 and file4. All files within the dir2 were created in the last 24 hours.
Identifying the files is possible using the –mtime option followed by the files time interval. In this case, the –1 option indicates 1 day, 24 hours. The –1 means the files created or modified on the last day, while +1 means the files created or modified more than a day ago.
In the following example, we use the find command with the -mtime option to remove the files created or modified the last day.
xargs vs -exec
The xargs command is almost always implemented with pipes (but not necessarily have to) to use the first command as an argument. Contrary to pipe, it allows the use of the first command as an argument and not only as a previous output or predecessor command.
The following example in this section lists the files and directories using the ls (List) command and moves the listed files to a different directory with mv and xargs commands. This is not the proper method to move the files, but it is useful as an example to show how the xargs command works.
First, give a look to my linuxhintdir directory. As you can see, we have 3 files: file1, file2 and file3.
Now, let’s move all the files within dir1 to dir2 using the mv command.
As you can see, the ls ~/dir1/* result was passed by xargs after the mv command.
The –exec command is similar to xargs. It can execute commands based on the output of the first command. Contrary to xargs, –exec executes the command every time a file matches the condition. If we use the –exec command to remove the files, it will remove them file by file. While xargs executes the command at once for all the matched files. This makes xargs a little faster than –exec. Therefore, if you are dealing with many files, xargs would be convenient over –exec.
Conclusion
Linux has many methods to achieve the same task. Finding and removing the files with a single command is a knowledge that any Linux user should have independently on his experience. This tutorial focuses on finding and deleting the files, but xargs and -exec can be used with many Linux commands. It is important to mention that some functions are available only in the find version. Most of the tips explained are useful for almost every Linux distribution.
Thank you for reading this tutorial explaining how to find and delete the files in Linux. Keep following us for more professional tips.
About the author
David Adams
David Adams is a System Admin and writer that is focused on open source technologies, security software, and computer systems.