Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

A variable var contains multiple arguments, each split by a new line.

echo "$var" | xargs -I % echo ABC %
#Results in:
#ABC One
#ABC Two
#ABC Three

However, when omitting -I and the % characters, I get the following:

echo "$var" | xargs echo ABC
#Results in:
#ABC One Two Three

I've once read {} would substitute for the current argument (like find does), but that does not happen. What am I doing wrong?

share|improve this question
add comment

2 Answers

If you use GNU Parallel instead of xargs you can control which behaviour you want:

# 1 line at a time
echo "$var" | parallel echo ABC {}
# Many lines at a time (divided by # cpu)
echo "$var" | parallel -X echo ABC {} 
# Many lines at a time (not divided)
echo "$var" | parallel -Xj1 echo ABC {} 

It takes literally 10 seconds to install GNU Parallel:

wget pi.dk/3 -qO - | sh -x

Watch the intro videos to learn more: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

share|improve this answer
add comment

The usual behavior of xargs is to paste as many arguments as possible onto the command line of any command it runs, iterating 'till it's done them all. When used this way, it's a solution to the problem of command line length limitations.

But when you specify the -I option, it runs the command on each argument individually, one-at-a-time. I don't think that's completely obvious in the documentation of the Linux xargs -I option but that's what they mean.

-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.
share|improve this answer
    
Also, unquoted blanks do not terminate input items; instead the separator is the newline character. — this is central to understanding the behavior. Without -I, xargs only sees the input as a single field, since newline is not a field separator. With -I, suddenly newline is a field separator, and thus xargs sees three fields (that it iterates over). That is a real subtle point, but is explained in the man page quoted. –  Daniel Andersson Feb 26 '13 at 6:57
    
@DanielAndersson That's true, but that's not what the OP found confusing. –  Nicole Hamilton Feb 26 '13 at 8:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.