Objective: to list files in all jars.
This works:
for f in `find . -name "*.jar"`; do jar tvf $f; done
This works too:
find . -name "*.jar" -exec jar tvf {} \;
This does not (it does not print any output):
find . -name "*.jar" | xargs jar tvf
Why does the latter not work?
Does this works
find . -name "*.jar"|xargs -n 1 jar -tvf
The problem is that jar tvf
only allows one file to be passed in.
The for loop runs the files one by one
jar tvf 1.jar; jar tvf 2.jar; ...
However, xargs tries to fit as many arguments on one line as possible. Thus it's trying the following:
jar tvf 1.jar 2.jar ...
You can verify this by placing an echo in your command:
for f in `find . -name "*.jar"`; do echo jar tvf $f; done
find . -name "*.jar" | xargs echo jar tvf
The proper solution is the tell xargs to only use one parameter per command:
find . -name "*.jar" | xargs -n 1 jar tvf
or
find . -name "*.jar" | xargs -I{} jar tvf {} # Find style parameter placement
It does not work because xargs invoke only one process with all arguments.
There is a way to invoke a new process for each argument using -I'{}'
.
Try this to understand:
$ 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With