Delete a list of files with find and grep
GrepFindPipeRmGrep Problem Overview
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?
Grep Solutions
Solution 1 - Grep
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.
Solution 2 - Grep
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
Solution 3 - Grep
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.
Solution 4 - Grep
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 (seeman find
for details)rm --
makes sure to actually remove files starting with a-
instead of treating them as parameters torm
. In case there is a file called-rf
and dofind . -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.
Solution 5 - Grep
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 {} \;
Solution 6 - Grep
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.
Solution 7 - Grep
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.
Solution 8 - 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.
Solution 9 - Grep
find start_dir -iname \*car\* -exec rm -v {} \;
Solution 10 - Grep
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.
Solution 11 - Grep
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
tellsgrep
to print only filenames-R
enablesgrep
recursive search in subfolders-Z
tellsgrep
to separate results by\0
instead of\n
-0
tellsxargs
to separate input arguments by\0
instead of whitespacecar
is the regular expression to search for.
is the folder where to search
Can also use rm -f
to force the removal (as usual).