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.
精彩评论