I'm trying to delete a bunch of files in a certain directory (on Mac OS X using Terminal)
ls | grep \([1-9]\) | xargs rm
should do the trick, but it doesn't. I'm trying to delete any file with a single digit in parentheses in the filename (duplicates downloaded from the web), but it ends up doing something like this:
> rm: 520syllabus2010: No such file or
> directory rm: (3).pdf: No such file or
> directory
because it doesn't interpret the space correct. It should delete "520syllabus2010 (3).pdf"
What's the proper way of doing this?
Thanks,
Jeff
Best Answer
Short version:
Do not pipe
ls
toxargs
. Instead, pipefind ... -print0
toxargs -0
, in order to avoid such problems....which can be written as:
and:
which can further be shortened to just
rm
with a wildcard.Normally,
ls
andfind
separate file names with newlines, butxargs
splits its input by newline or space, resulting in the behavior you see.It's possible tell
xargs
to split only by newline, but files can have newlines in their names too. In fact, on Linux and BSD, the only disallowed character is the "null" or zero byte – so it's what you should use in such cases.In example 2 above,
-print0
tellsfind
to separate filenames with a null byte; same forxargs -0
. (A few other tools also have similar options, such assort -z
orgrep -zZ
.)The "short version" uses a simple shell wildcard ("pattern" in
bash
manual – see section "Pathname Expansion").