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.
-
Related post - How do I recursively delete directories with wildcard?– RBTDec 6, 2019 at 9:37
8 Answers
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:
-
1
-
24
-
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.– HennesNov 15, 2013 at 13:14 -
16@Hennes Be careful with
rm -r *.bak
! It also removes directories ending in.bak
with all their content. Nov 15, 2013 at 13:34 -
65Make sure that
-delete
is the last argument in your command. If you put it before the-name *.bak
argument, it will delete everything.– MichaelOct 29, 2014 at 14:36
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).
-
-
Not working in WSL with git bash. Says "rm: cannot remove '*/.md': No such file or directory " Apr 8 at 9:43
-
@MarianKlühspies That just means there are no matching files. Apr 8 at 10:18
-
@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 Apr 8 at 10:50
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. Apr 4, 2014 at 20:11 -
2you are probably right, it's just an alternative solution, perhaps more raw ;)– lokersApr 4, 2014 at 22:13
-
18This is not just an alternative but an example how other commands can be combined together with the pipe '|'. +1 Jun 5, 2014 at 7:18
-
21This alternative solutions work on other environments that lack -delete (like cygwin)– ciriarteAug 15, 2014 at 4:07
-
3
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 {} +
-
7"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, 2013 at 15:12 -
2The package
trash-cli
does the same thing asgvfs-trash
without the dependency ongvfs
.– FlimmNov 20, 2013 at 9:08 -
I have edited it in the answer, next time feel free to do the edit yourself.– don.joeyNov 20, 2013 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
. Oct 14, 2017 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. Oct 14, 2017 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.
Quick Answer:
Delete all files with the considered name or postfix recursively:
find . -name '*.pyc' -type f -delete
Delete all directories with the considered name recursively:
find ~ -path '*/__pycache__/*' -delete find ~ -type d -name '__pycache__' -empty -delete
Somewhat less tightly controlled, but in a single line:
find ~ -path '*/__pycache__*' -delete
[NOTE]:
d
is directory option and f
is file option.
If in case you want to check the list before you delete the files, you can echo it.
find . -name "*.bak" -type f | xargs echo rm -rf
This will list out the search results that are piped to rm command via xargs. Once you are sure about the list you can drop the echo in above command.
find . -name "*.bak" -type f | xargs rm -rf
-
its a good practice to add
-print0 | xargs -0
to handle cornercase filenames, exampletest's
gives youxargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
or filenames with newlines will break.– user986805Nov 25, 2019 at 7:02
You can list all the files with that extension first before you use rm
For example,
ls *.bak
If you get only the files that you want to delete then you can use the rm
rm *.bak