Take the 2-minute tour ×

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

2 Answers 2

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

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


share|improve this answer

Your Answer


