935

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.

Glutanimate
  • 21,763
user216038
  • 9,353

10 Answers10

1511

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:

Radu Rădeanu
  • 174,089
  • 51
  • 332
  • 407
72

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).

61
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f
muru
  • 207,228
lokers
  • 719
26

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.

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 {} +
Zanna
  • 72,312
don.joey
  • 29,392
10

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.

6

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.

Benyamin Jafari
  • 4,234
  • 4
  • 27
  • 37
6

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
1

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
ijyrem
  • 19
  • 1
-1

Once you are confident that all your files of a particular extension (eg. .bak) has to be deleted, just use:

rm -ir *.bak

It will give you a prompt:

rm: remove regular file 'example.bak'? 

Answer the prompt with a y for Yes and n for No

-1

I think it can be as simple at find *.tgz -delete if we want to only remove the files in the current dir on the current level (not in the children folders).