6

I'm having some trouble with this command under bash in Ubuntu:

rm $(find . -name "*.exe")

My aim is to remove, recursively, all files ending in .exe. But some files have white spaces and this breaks the command.

Any suggestions on how to approach this problem?

4 Answers 4

17
find . -name "*.exe" -exec rm -f '{}' +

This has find format the command and arguments, and it carefully avoids mangling the names (by passing each one as a separate argument to rm). The '+' means "do as many as you can reasonably in one execution of rm".

2
  • 3
    find(1) has the -delete action (maybe just GNU find only) which will save all the subprocesses and cumbersome command line options. find . -name '*.exe' -delete
    – camh
    Jul 12, 2011 at 4:35
  • @camh: follow the link to the POSIX documentation; -delete is not included. It is in GNU find; the question is for Linux; so it is possible to use -delete. However, all the world is not Linux, and a portable answer maybe of use. Jul 12, 2011 at 4:44
3

You can pipe the output from find into xargs, specifying that only newlines should be considered as delimiters between filenames:

find -name '*.exe' | xargs -d \\n rm

The more portable way to do this is to use the null character as the delimiter:

find -name '*.exe' -print0 | xargs -0 /bin/rm

See find's manpage for an example that does this.

Another option is to use the command you used, but to set bash's internal argument delimiter to newlines-only:

IFS=$'\n'; rm $(find . -name "*.exe");

Here the $'...' quoting construct is used to create a newline character. This approach will be less resilient in the case of a long list of filenames than will using xargs.

2
  • 1
    There's no real point in using anything other than the -print0 and -0 options; the other doesn't work correctly if the names contain newlines (and that is a valid character in a Unix file name). Similarly with the IFS hack. Note that these are GNU-specific (though eminently sensible) extensions to the standard. Jul 12, 2011 at 4:47
  • @Jonathan: I usually use -d myself just because it's less typing, and in practice filenames (at least for me) never contain newlines. There's also the advantage that you can filter the output of find through other programs (grep, tail, etc) before sending it to xargs.
    – intuited
    Jul 12, 2011 at 10:50
1

Simply pass the -delete option to find:

find . -name "*.exe" -delete

This saves you from quoting and any other filename hassles and is presumably faster than -exec because no new processes need to be spawned.

0
0

Manually escaping the characters may help you.

find . -name "*.exe" | sed -s 's/\ /\\ /' | xargs rm -f
2
  • Not a reliable technique; all else apart, xargs splits names at blanks. You might use find . -name "*.exe" -print0 | xargs -0 rm -f, where the -print0 ends file names with ASCII NUL and the -0 means that xargs reads names ending with ASCII NUL. Note that these are GNU-specific (though eminently sensible) extensions to the standard. Jul 12, 2011 at 4:46
  • @Jonathan True.. Your answer is definitely better.
    – Overmind Jiang
    Jul 12, 2011 at 5:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .