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.
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:
find . -name "*.bak" -type f
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:
-
-
8
-
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 Nov 15 '13 at 13:14 -
9@Hennes Be careful with
rm -r *.bak
! It also removes directories ending in.bak
with all their content. – Radu Rădeanu Nov 15 '13 at 13:34 -
34Make sure that
-delete
is the last argument in your command. If you put it before the-name *.bak
argument, it will delete everything. – Michael Oct 29 '14 at 14:36
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f
-
1Welcome 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 offind
. More information can be found in the GNU manuals entry for deleting files with find. – Glutanimate Apr 4 '14 at 20:11 -
2you are probably right, it's just an alternative solution, perhaps more raw ;) – lokers Apr 4 '14 at 22:13
-
10This is not just an alternative but an example how other commands can be combined together with the pipe '|'. +1 – Boris Pavlović Jun 5 '14 at 7:18
-
11This alternative solutions work on other environments that lack -delete (like cygwin) – ciriarte Aug 15 '14 at 4:07
-
2
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:
rm **/*.bak
(or gvfs-trash **/*.bak
or what have you).
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 asgvfs-trash
without the dependency on gvfs.
So:
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.
find . -name '*.bak' -xtype f
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 {} +
-
3"Don't use
rm
to delete things" is a controversial statement but I have to agree that it's often wiser to use something that will let you undo things. – Oli♦ Nov 15 '13 at 15:12 -
2The package
trash-cli
does the same thing asgvfs-trash
without the dependency ongvfs
. – Flimm Nov 20 '13 at 9:08 -
I have edited it in the answer, next time feel free to do the edit yourself. – don.joey Nov 20 '13 at 10:06
-
@don.joey This answer seems to say
find . -name "*.bak" -type f
displays whattrash *.bak
deletes. Is that really what you mean? You can move directories to the trash withtrash
orgvfs-trash
, buttrash *.bak
will only moves files and directories whose names end with.bak
and that reside immediately in the current directory. The shell expands*.bak
, sotrash *.bak
won't affect.bak
files in subdirectories not themselves named.bak
. – Eliah Kagan Oct 14 '17 at 2:30 -
1@don.joey Yes
ls *.bak
(which I think you mean) lists whattrash *.bak
trashes.find . -name '*.bak' -xtype f -exec trash {} +
trashes all.bak
files anywhere under.
. It can't use an alias, so installtrash-cli
or writegvfs-trash
instead. Here's an example.-xtype f
selects files and symlinks to files, but not folders. To delete.bak
folders too, usefind . -name '*.bak' -execdir trash {} +
, which avoidscannot trash non existent
errors for.bak
files inside.bak
directories. Please feel free to use any of this in your answer. – Eliah Kagan Oct 14 '17 at 19:15
If you want to delete all files of a certain type, but only 1 folder "deep" from the current folder:
find . -maxdepth 2 -name "*.log" -type f -delete
-maxdepth 2 because the current directory "." counts as the first folder.
If you are inside a git repo, you can use:
git clean -fdx
This deletes untracked files and files in .gitignore.