xargs
does all the magic:
find . -name test -type d -print0|xargs -0 rm -r --
xargs
executes the command passed as parameters, with the arguments passed to stdin.
This is using rm -r
to delete the directory and all its children.
The --
denotes the end of the arguments, to avoid a path starting with -
from being treated as an argument.
-print0
tells find
to print \0
characters instead of newlines; and -0
tells xargs
to treat only \0
as argument separator.
This is calling rm
with many directories at once, avoiding the overhead of calling rm
separately for each directory.
As an alternative, find
can also run a command for each selected file:
find . -name test -type d -exec rm -r {} \;
And this one, with better performance, since it will call rm
with multiple directories at once:
find . -name test -type d -exec rm -r {} +
(Note the +
at the end; this one is equivalent to the xargs
solution.)
You have already provided a find
command that is safe for oddly named files:
find -regextype posix-egrep -type f -regex '.*[^/]{5}' -delete
This regex matches five trailing characters that do not contain a slash (i.e. the filename is longer than five chars).
The Bash loop you provided will generally work, but it probably does not scale with thousands of files and may break with special filenames.
An alternative that is similar in efficiency, but may provide more flexibility (replace rm
by -n1 echo
to print all files):
find -type f -print0 | grep -Ez '[^/]{5}$' | xargs -0 rm
The -print0
, -z
and -0
options ensure that each file name is terminated with a NUL byte. This ensures that special characters do not split filenames (newlines break the Bash command you provided). Although this grep command
still fails with a name such as path/abc\ndef
(where \n
is a newline), it won't be split up into path/abc
and def
.
As you will rarely find files with \n
in their name, I leave the implementation for that case as an exercise to the reader.
Best Answer
The syntax is a little bit tricky: