开发者

subtle difference in using xargs and xargs -i

Why does find . -name "*.xml" | xargs grep FOO returns matchs with filenames, while find . -name "*.xml" | 开发者_开发百科xargs -i -sh -c "grep FOO {}" doesn't?


Unless it's a typo in posting your question there shouldn't be a hyphen before sh:

The reason you don't get filenames in the output is that grep is being run with a single file as an argument. To force filename output use -H.

find . -name "*.xml" | xargs -I {} sh -c "grep -H FOO {}"

Also, -i for xargs was deprecated around version 4.2.9. You should use -I {}.


As a previous answer said, the difference is that grep is being invoked for each file and grep doesn't report the filename if only one file is specified on the command line unless the -H (--with-filename) flag is given.

Why is grep being invoked for each file? That is because (like it or not) the use of the -I (or -i) flag to xargs forces the command to be run once for each argument, like using flag "-L 1" to xargs.

From the manual page:

   -I replace-str
     Replace occurrences of replace-str in the initial-arguments with names read from
     standard input.  Also, unquoted blanks do not terminate input items; instead the
     separator is the newline character.  Implies -x and -L 1.


you can just use

find . -name "*.xml" | xargs -I{} grep FOO {}

and you may use -H or -n in grep command as you need.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜