Delete a list of files with find and grep
Asked Answered
M

12

85

I want to delete all files which have names containing a specific word, e.g. "car". So far, I came up with this:

find|grep car

How do I pass the output to rm?

Menedez answered 31/12, 2013 at 14:0 Comment(0)
R
162
find . -name '*car*' -exec rm -f {} \;

or pass the output of your pipeline to xargs:

find | grep car | xargs rm -f

Note that these are very blunt tools, and you are likely to remove files that you did not intend to remove. Also, no effort is made here to deal with files that contain characters such as whitespace (including newlines) or leading dashes. Be warned.

Rattlepate answered 31/12, 2013 at 14:2 Comment(7)
Maybe even find . -name '*car*' -delete.Deathwatch
+1. But on the first few runs: change "rm" to "echo rm" ... and verify that it only outputs file you really want to delete, and no others ^^Canonize
@nhahtdh: xargs: illegal option -- d; all the world is not LInux. And what about directories that contain \n in their name? If you worry about whitespace, you should use find --print0 ... xargs -0Rattlepate
@WilliamPursell: You are right, the method with -0 is much better. For the sake of completeness, there is -Z option in grep. Would you please also include that in your answer? (Anyway, regarding the compatibility issue, the print null option is not in the POSIX standard, though I don't know how well these options are actually supported in the wild).Voucher
alias cleandesktop="find ~/Desktop/ -name '*Screen Shot*' -exec rm -f {} \;" BOOM. Yes.Lengthy
Please be aware that this will not work if your files contain unusual characters (like spaces) or start with a dash. Please see my answer for a fix.Merlon
This can be safer making rm ask you for confirmation on each removal by using rm -fi.Scathe
S
30

To view what you are going to delete first, since rm -fr is such a dangerous command:

find /path/to/file/ | grep car | xargs ls -lh

Then if the results are what you want, run the real command by removing the ls -lh, replacing it with rm -fr

find /path/to/file/ | grep car | xargs rm -fr
Soar answered 29/2, 2016 at 18:33 Comment(1)
Amazing solution! Thank you!Seer
W
11

I like to use

rm -rf $(find . | grep car)

It does exactly what you ask, logically running rm -rf on the what grep car returns from the output of find . which is a list of every file and folder recursively.

Wholly answered 19/12, 2016 at 14:32 Comment(1)
argument list too long to run: rmNeona
M
6

You really want to use find with -print0 and rm with --:

find [dir] [options] -print0 | grep --null-data [pattern] | xargs -0 rm --

A concrete example (removing all files below the current directory containing car in their filename):

find . -print0 | grep --null-data car | xargs -0 rm --

Why is this necessary:

  • -print0, --null-data and -0 change the handling of the input/output from parsed as tokens separated by whitespace to parsed as tokens separated by the \0-character. This allows the handling of unusual filenames (see man find for details)
  • rm -- makes sure to actually remove files starting with a - instead of treating them as parameters to rm. In case there is a file called -rf and do find . -print0 | grep --null-data r | xargs -0 rm, the file -rf will possibly not be removed, but alter the behaviour of rm on the other files.
Merlon answered 24/10, 2017 at 18:9 Comment(2)
On MacOS, --null-data is an "unrecognized option". Would --null be the equivalent option for grep?Cyclohexane
@SteveS for mac there's a simpler way: apple.stackexchange.com/questions/120399/… (i could not figure out how to do it with grep and xargs, sadly)Lustihood
T
5

You can use ls and grep to find your files and rm -rf to delete the files.

rm -rf $(ls | grep car)

But this is not a good idea to use this command if there is a chance of directories or files, you don't want to delete, having names with the character pattern you are specifying with grep.

Tirza answered 24/9, 2018 at 6:53 Comment(1)
Variation if one is interested in a file content instead: $ grep -l 'proto' /etc/apt/sources.list /etc/apt/sources.list.d/* | xargs -or rm -iv rm: remove write-protected regular file '/etc/apt/sources.list.d/protonvpn-stable.list'? y rm: cannot remove '/etc/apt/sources.list.d/protonvpn-stable.list': Permission denied ...Mural
D
3

This finds a file with matching pattern (*.xml) and greps its contents for matching string (exclude="1") and deletes that file if a match is found.

find . -type f -name "*.xml" -exec grep exclude=\"1\" {} \; -exec rm {} \;
Dishonest answered 2/5, 2018 at 12:42 Comment(0)
T
3

Most of the other solutions presented here have problems with handling file names with spaces in them. Here's a solution that handles spaces properly.

grep -lRZ car . | xargs -0 rm

Notes on arguments used:

  • -l tells grep to print only filenames
  • -R enables grep recursive search in subfolders
  • -Z tells grep to separate results by \0 instead of \n
  • -0 tells xargs to separate input arguments by \0 instead of whitespace
  • car is the regular expression to search for
  • . is the folder where to search

Can also use rm -f to force the removal (as usual).

Thereby answered 5/12, 2021 at 16:14 Comment(0)
E
1

A bit of necromancy, but you can also use find, grep, and xargs

find . -type f | grep -e "pattern1" -e "pattern2" | xargs rm -rf

^ Find will need some attention to make it work for your needs potentially, such as is a file, mindepth, maxdepth and any globbing.

Escalate answered 18/8, 2017 at 13:30 Comment(0)
T
1

when find | grep car | xargs rm -f get results:

/path/to/car  
/path/to/car copy  

some files which contain whitespace will not be removed.

So my answer is:

find | grep car | while read -r line ; do 
  rm -rf "${line}"
done

So the file contains whitespace could be removed.

Tavis answered 28/4, 2019 at 7:16 Comment(0)
M
0
find start_dir -iname \*car\* -exec rm -v {} \;
Misestimate answered 31/12, 2013 at 14:3 Comment(0)
M
0

I use:

find . | grep "car" | while read i; do echo $i; rm -f "$i"; done

This works even if there are spaces in the filename as well as in recursive manner, searching for directories as well.

Monocyclic answered 11/8, 2022 at 14:55 Comment(0)
E
-1

Use rm with wildcard * rm * will delete all files rm *.ext will delete all files which have ext as extension rm word* will delete all files which starts with word.

Effective answered 10/2, 2021 at 23:22 Comment(1)
The situation stated is a bit more complicated and this may not work in most of the cases.Monocyclic

© 2022 - 2024 — McMap. All rights reserved.