11

I'm trying to write a bash command that will delete all files matching a specific pattern - in this case, it's all of the old vmware log files that have built up.

I've tried this command:

find . -name vmware-*.log | xargs rm

However, when I run the command, it chokes up on all of the folders that have spaces in their names. Is there a way to format the file path so that xargs passes it to rm quoted or properly escaped?

Dan Monego
  • 9,637
  • 6
  • 37
  • 72

7 Answers7

23

Try using:

find . -name vmware-*.log -print0 | xargs -0 rm

This causes find to output a null character after each filename and tells xargs to break up names based on null characters instead of whitespace or other tokens.

Emil Sit
  • 22,894
  • 7
  • 53
  • 75
9

Do not use xargs. Find can do it without any help:

find . -name "vmware-*.log" -exec rm '{}' \;

L.R.
  • 977
  • 6
  • 22
  • 3
    It's always good to avoid starting an extra process, especially something like this where you could provide something way too long to xargs. Note that `find` even has a `delete` action you can use instead of the `-exec ...` - but it's easier to customize this way. You also don't have to quote the curly braces, unless you're using an old shell like tcsh. – Cascabel Oct 19 '09 at 18:35
  • 4
    But this will launch an `rm` process for each file individually, instead of passing several filenames to `rm` like `xargs` does, so it's going to be slower. – JaakkoK Oct 19 '09 at 18:37
  • 6
    @jk: That's why newer `find` implementations have `find -exec rm '{}' +`, which will batch up arguments just like `xargs` does. – ephemient Oct 19 '09 at 18:53
  • @jk: You're right about the processes. As for the speed, there are always exceptions, but in my experience, it's not the rm process-starting that dominates. If you're deleting enough files that the rm time wins out, it's the actual disk activity holding you up. Otherwise it's the find time that matters anyway (think 5 matches out of 10000 files). – Cascabel Oct 19 '09 at 19:03
  • @ephemient: Good call. I'd totally forgotten that! – Cascabel Oct 19 '09 at 19:03
5

Check out the -0 flag for xargs; combined with find's -print0 you should be set.

find . -name vmware-*.log -print0 | xargs -0 rm
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
4

GNU find

find . -name vmware-*.log -delete
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
1

find . -name vmware-*.log | xargs -i rm -rf {}

biegleux
  • 13,179
  • 11
  • 45
  • 52
rh0dium
  • 6,811
  • 4
  • 46
  • 79
0

To avoid space issue in xargs I'd use new line character as separator with -d option:

find . -name vmware-*.log | xargs -d '\n' rm
Ray
  • 5,269
  • 1
  • 21
  • 12
0
find -iname pattern

use -iname for pattern search

simont
  • 68,704
  • 18
  • 117
  • 136
nkvnkv
  • 914
  • 2
  • 12
  • 25