xargs -I replace-str选项的区别


16

据我了解,以下含义应完全相同:

ls -1 | xargs file {}
ls -1 | xargs -I{} file {}

如果未指定-I选项,则默认为-I {}。

我想列出当前目录中的所有文件,并对每个文件运行file命令。有些名称中有空格。但是,我注意到了差异。见下文:

$ ls -1
Hello World
$ ls -1 | xargs file {}
{}:    ERROR: cannot open `{}' (No such file or directory)
Hello: ERROR: cannot open `Hello' (No such file or directory)
World: ERROR: cannot open `World' (No such file or directory)
$ ls -1 | xargs -I{} file {}
Hello World: directory

显式指定-I {}时,文件名中的空格将按预期方式处理。


3
“如果未指定-I选项,则默认为-I {}” –这是错误的,至少对于GNU xargs而言是这样。
jjlin

我理解我的错误。我应该指定xargs filexargs -I{} file {}。不应该这样xargs file {}。我猜想在显式指定-I {}时,bash会将其视为file "Hello World"。如果没有-I {},则将其视为file Hello World
foresightyj

1
(1)此讨论与shell(bash)无关。(2)最好知道的-1选项ls,但是当输出ls是文件或管道时,默认情况下它处于启用状态,因此在这里不需要它。(3)您-I对已弃用-i(小写I)选项感到困惑。 -ifoo等同于-Ifoo,但普通-i等同于-I{}。但是使用-I{}。(4)如果您确实想做自己想做的事情,为什么不随便说呢file *
斯科特,

@Scott我的初衷是写`find。名称“ * .mov” | xargs -I {}文件{}`可以递归查找所有mov文件并file在其上运行。但是我想出了一个使用的简单示例ls。你是对的。为此,file *是最好的。
foresightyj

1
找到-exec
Cristian Ciupitu

Answers:


20

-I需要定义占位符。该-i选项将假定{}为占位符。在这里man xargs,至少在Cygwin和CentOS上我发现了{}的任何假设。

不带任何选项调用的xargs不需要占位符,它只是将STDIN附加到参数的末尾。

只需添加echo示例即可查看xargs在做什么:

$ ls -1
Hello World/

您的示例错误地使用了{}

$ ls -1 | xargs echo file {}
file {} Hello World/

因此,filecmd会看到{} Hello World和错误的参数。

如果要{}在xargs调用中明确使用:

$ ls -1 | xargs -i echo file {}
file Hello World/

或不带占位符:

$ ls -1 | xargs echo file
file Hello World/

如上所述的xargs不需要{}。它将STDIN附加到命令的末尾,不带占位符。使用{}通常意味着您要在cmd中间的某个位置执行STDIN,如下所示:

$ ls -1 | xargs -i mv {} /path/to/someplace/.

这很清楚。即使您的答案有点晚,但阅读它确实可以加强我的理解。
foresightyj
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.