bash 使用 xargs 和 xargs -i 的细微差别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5192564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:33:56  来源:igfitidea点击:

subtle difference in using xargs and xargs -i

bashgrepxargs

提问by shabunc

Why does find . -name "*.xml" | xargs grep FOOreturns matchs with filenames, while find . -name "*.xml" | xargs -i -sh -c "grep FOO {}"doesn't?

为什么find . -name "*.xml" | xargs grep FOO返回与文件名匹配,而find . -name "*.xml" | xargs -i -sh -c "grep FOO {}"没有?

回答by Paused until further notice.

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

除非在发布您的问题时有错别字,否则之前不应有连字符sh

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

您没有在输出中获得文件名的原因grep是正在以单个文件作为参数运行。要强制输出文件名,请使用-H.

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

Also, -ifor xargswas deprecated around version 4.2.9. You should use -I {}.

此外,-iforxargs已在 4.2.9 版左右弃用。你应该使用-I {}.

回答by Mark Polhamus

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.

正如之前的回答所说,不同之处在于为每个文件调用 grep 并且如果在命令行上仅指定一个文件,则 grep 不会报告文件名,除非给出 -H (--with-filename) 标志。

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.

为什么为每个文件调用 grep?那是因为(不管喜欢与否)将 -I(或 -i)标志用于 xargs 强制命令为每个参数运行一次,就像对 xargs 使用标志“-L 1”一样。

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.
   -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.

回答by justin.yqyang

you can just use

你可以使用

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

and you may use -Hor -nin grepcommand as you need.

并且您可以根据需要使用-H-ngrep命令中。