【发布时间】:2011-09-30 21:33:06
【问题描述】:
目标:列出所有 jar 中的文件。
这行得通:
for f in `find . -name "*.jar"`; do jar tvf $f; done
这也有效:
find . -name "*.jar" -exec jar tvf {} \;
这不(它不打印任何输出):
find . -name "*.jar" | xargs jar tvf
为什么后者不起作用?
【问题讨论】:
目标:列出所有 jar 中的文件。
这行得通:
for f in `find . -name "*.jar"`; do jar tvf $f; done
这也有效:
find . -name "*.jar" -exec jar tvf {} \;
这不(它不打印任何输出):
find . -name "*.jar" | xargs jar tvf
为什么后者不起作用?
【问题讨论】:
这行得通吗
find . -name "*.jar"|xargs -n 1 jar -tvf
【讨论】:
问题是jar tvf只允许传入一个文件。
for循环一个一个地运行文件
jar tvf 1.jar; jar tvf 2.jar; ...
但是,xargs 试图在一行中容纳尽可能多的参数。因此它正在尝试以下操作:
jar tvf 1.jar 2.jar ...
您可以通过在命令中添加回显来验证这一点:
for f in `find . -name "*.jar"`; do echo jar tvf $f; done
find . -name "*.jar" | xargs echo jar tvf
正确的解决方案是告诉 xargs 每个命令只使用一个参数:
find . -name "*.jar" | xargs -n 1 jar tvf
或
find . -name "*.jar" | xargs -I{} jar tvf {} # Find style parameter placement
【讨论】:
-i 的提示,很好。
-i) 已被弃用。见 man xargs (xargs (GNU findutils) 4.4.2): This option is deprecated; use -I instead. 在交互模式下使用它没有问题,但我会在脚本中避免它,因为它可能会在未来版本的 xargs 中消失。
它不起作用,因为 xargs 只调用一个带有所有参数的进程。
有一种方法可以使用-I'{}' 为每个参数调用一个新进程。
试试这个就明白了:
$ seq 10 | xargs echo
1 2 3 4 5 6 7 8 9 10
$ seq 10 | xargs -I'{}' echo {}
1
2
3
4
5
6
7
8
9
10
【讨论】: