Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

One of my common practices is to perform greps on all files of a certain type, e.g., find all the HTML files that have the word "rumpus" in them. To do it, I use

find /path/to -name "*.html" | xargs grep -l "rumpus"

Occasionally, find will return a file with a space in its name such as my new file.html. When xargs passed this to grep, however, I get these errors:

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory

I can see what's going on here: either the pipe or the xargs is treating the spaces as delimiters between files. For the life of me, though, I can't figure out how to prevent this behavior. Can it be done with find + xargs? Or do I have to use an entirely different command?

share|improve this question
add comment

2 Answers

up vote 10 down vote accepted

Use

find ... -print0 | xargs -0 ...

e.g.

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

from the find man page

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
share|improve this answer
add comment

You do not need to use xargs, because find can execute commands itself. When doing this, you do do not have to worry about the shell interpreting characters in the name.

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

from the find man page

-exec command {} +
This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.

share|improve this answer
    
I would upvote this but I have non left for today - I'll do it tomorrow. –  Iain May 10 '11 at 21:37
1  
@Iain - there you go (I agree, by the way). –  Eduardo Ivanec May 10 '11 at 21:41
    
Just using find you still miss out on features of xargs, plus you have to deal with silly quoting rules. See the -P argument to xargs if you have more than one core / CPU. –  Slartibartfast May 11 '11 at 3:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.