is it possible to use rm to remove files and directories matching a pattern recursively without using other commands?
5 Answers
To directly answer your question, "no - you can't do what you describe with rm
".
You can, however, do it you combine it with find
. Here's one of many ways you could do that:
# search for everything in this tree, search for the file pattern, pipe to rm
find . | grep <pattern> | xargs rm
For example, if you want to nuke all *~ files, you could so this:
# the $ anchors the grep search to the last character on the line
find . -type f | grep '~'$ | xargs rm
To expand from a comment*:
# this will handle spaces of funky characters in file names
find -type f -name '*~' -print0 | xargs -0 rm
-
1true - if you leave-out the last pipe, you'll get a list of everything first :)– warrenOct 27, 2009 at 5:48
-
2May not directly answer the poster's question, but is the closest they will get to what they want.– DrakiaOct 27, 2009 at 16:35
-
1
-
10Please be very careful using
find | grep | xargs rm
. If there are files with spaces (or newlines), this will break (and depending on the filenames and where the spaces are) might delete stuff that you did not intend to delete.find … -print0 | xargs -0 rm
will be much more robust. It will mean, however that you cannot usegrep
and must usefind
's predicates to match and print0 only the desired files. warren's second example will be more robust asfind -type f -name '*~' -print0 | xargs -0 rm
. Oct 28, 2009 at 5:20 -
1If you want a single command to do the job, make an alias using one of the find commands given. Will fill in an answer for this later, if desired. Nov 7, 2009 at 18:09
"without using other commands"
No.
-
Nice answer illustrating the "strictly answer the initial question (at the risk of not being able to provide a solution)" vs. "provide a solution, even if it's not strictly matching to imposed restrictions" debate.– GnoupiOct 27, 2009 at 16:59
-
I only posted this as "A Dwarf" was complaining about the answer that actually provided a solution. Without using other commands there really is no way to do recursive file deletion that matches a pattern, just current-directory file/directory deletion.– DrakiaOct 27, 2009 at 18:29
Using Bash, with globstar
set, yes:
rm basedir/**/my*pattern*
Try it with e.g. ls -1
first, before rm
to list the files you match.
You set options through e.g. shopt -s globstar
.
Alternatively, a shorter find
variant:
find -type f -name 'my*pattern*' -delete
or for GNU find
:
find -type f -name 'my*pattern*' -exec rm {} +
or another alternative for non-GNU find
(a bit slower):
find -type f -name 'my*pattern*' -exec rm {} \;
To also remove directories, as you ask for: just change rm
into rm -r
in the above commands and skip matching on only -type f
in the find
commands.
I would have asuumed " rm -rf " where is a combination of file names, and matching patterns such as * and ? etc (eg todays_log_2009????.log) . That will start from current Dir and work down recursively removing files that macth that pattern.
-
This won't work because the pattern is expanded by the shell in the current directory. If quoted, the pattern becomes a filename with special characters in it. e.g. to delete the file [, one could write rm '[' . The pattern simply loses its meaning. Nov 7, 2009 at 18:02
If you use zsh(1), turn on "extended globbing" with setopt extendedglob
in .zshrc. Prefixing the pattern with '**/' will then delete recursively:
% rm -rf **/< pattern >
However, if there are a lot of files to delete you should resort to find(1) with xargs(1) or -exec, and I also recommend doing that in shell scripts.