LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Xargs with output of find (http://www.linuxquestions.org/questions/programming-9/xargs-with-output-of-find-891874/)

thund3rstruck 07-15-2011 07:57 AM

Xargs with output of find
 
Hi guys,

I'm testing some multi-plat java code and I'm getting a bit frustrated with the Linux tests. I need to run the command:

Code:

$ java -jar /home/developer/TCO/TabletComicOptimizer.jar <file> <args[]>
against all the files that match a specific criteria. I've tried various find syntax and I can't seem to get it right.

Normally I would just create a bash script and populate the results of find into an array and then just enumerate the collection but in this specific case I want to demonstrate this operation at the bash terminal.

I've tried things like:

Code:

~/TCO $ find . -type f -iname "*.cb[rz]" | xargs java -jar TabletComicOptimizer.jar {} 1200x1800 \;
Thinking that the {} is the substitution for each file returned by find but it's not working.

How do I execute my java program against each result in the find operation?

Thanks!

thund3rstruck 07-15-2011 08:08 AM

Ugh...

-exec is what I actually need:

Code:

~/AndriodDev/Comics/Batman - Arkham Reborn $ find . -iname "*.cb[rz]" -exec java -jar ~/Downloads/jComicOptimizer/TabletComicOptimizer.jar "{}" \;
Got it... sheesh... that was a bit embarrassing :)

druuna 07-15-2011 08:09 AM

Hi,

Have you tried not using xargs, but find's -exec operand?
Code:

find . -type f -iname "*.cb[rz]" -exec java -jar TabletComicOptimizer.jar {} 1200x1800 \;
Hope this helps.

EDIT: Answer was found while I was typing :)

crts 07-15-2011 09:02 AM

Quote:

Originally Posted by thund3rstruck (Post 4415622)
Ugh...

-exec is what I actually need:

Code:

~/AndriodDev/Comics/Batman - Arkham Reborn $ find . -iname "*.cb[rz]" -exec java -jar ~/Downloads/jComicOptimizer/TabletComicOptimizer.jar "{}" \;

Hi,

if using 'find' then -exec is the way to go. If you pipe the output of another program to 'xargs' then this is how you can handle the substitutions explicitly:
Code:

... | xargs -I '{}' echo '{} and some other text'
If you do not specify the -I option then the piped input will just be appended at the end of the command that 'xargs' executes.
So the 'xargs' equivalent 'find -exec' in your initial post would be:
Code:

~/TCO $ find . -type f -iname "*.cb[rz]" | xargs -I '{}' java -jar TabletComicOptimizer.jar {} 1200x1800
BTW, you do not have to use curly braces. You can specify almost any other String as placeholder.

thund3rstruck 07-15-2011 12:28 PM

Quote:

Originally Posted by crts (Post 4415669)
If you pipe the output of another program to 'xargs' then this is how you can handle the substitutions explicitly:
Code:

... | xargs -I '{}' echo '{} and some other text'
If you do not specify the -I option then the piped input will just be appended at the end of the command that 'xargs' executes.

Excellent feedback! Thank you. I was a little baffled as to why xargs was not working and it was that I switch.

Outstanding!

David the H. 07-17-2011 02:20 AM

By the way, you don't need to use '{}' with -I; any character string will do*. I prefer using '@' myself, as it's not a reserved shell character and so doesn't need quoting.

Also remember to use the null separator when working with filenames that can contain spaces.
Code:

~/TCO $ find . -type f -iname "*.cb[rz]" -print0 | xargs -I @ -0 java -jar TabletComicOptimizer.jar @ 1200x1800
As for find with -exec, replacing the final ';' with '+' tells it to run the operation in xargs-like batch mode, on all the filenames at once**.
Code:

find . -f -exec foo "{}" \+

#Executes as "foo file1 file2 file3 ..."

Notice that the "{}" must now appear exactly once, at the end of the command, and will expand to the entire list of filenames. So be sure that your command can handle that kind of input.

--
* Using gnu xargs and find, of course. Other implementations may not have the same features.
** Or as many as the command buffer will hold at a time, if the list is large.

thund3rstruck 07-17-2011 08:26 AM

Quote:

Originally Posted by David the H. (Post 4417081)
As for find with -exec, replacing the final ';' with '+' tells it to run the operation in xargs-like batch mode, on all the filenames at once**.
Code:

find . -f -exec foo "{}" \+

#Executes as "foo file1 file2 file3 ..."


Again, outstanding response! Thank you. Yea, this specific Java/Andriod application doesn't use named parameters so it expects a filepath as the first argument and an optional set of dimensions as the second argument. It doesn't understand a space delimited sequence of files and at first glance that's exactly what find was appearing to send in its output. Before I got your excellent response I was going to try a printf %s\n in the find to see if it functioned differently. Thankfully, I was just employing xargs incorrectly.

Thanks again!


All times are GMT -5. The time now is 06:48 AM.