Delete a list of files with find and grep

Viewed 110297

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?

12 Answers

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.

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 {} \;

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.

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.

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

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.

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.

Related