Fixed last argument with xargs

tl;dr; this is how you could do it portably, without -I and other broken fancy options:

$ echo a b c d f g | xargs -n 2 sh -c 'echo "$@" LAST' sh
a b LAST
c d LAST
f g LAST

$ seq 1 100000 | xargs sh -c 'echo "$#" LAST' sh
23692 LAST
21841 LAST
21841 LAST
21841 LAST
10785 LAST

The problem with the -I option is that it's broken by design, and there is no way around it:

$ echo a b c d f g | xargs -I {} -n 1 echo {} LAST
a b c d f g LAST
$ echo a b c d f g | xargs -I {} -n 2 echo {} LAST
{} LAST a b
{} LAST c d
{} LAST f g

But they're probably covered, because that's what the standard says:

-I replstr ^[XSI] [Option Start] Insert mode: utility is executed for each line from standard input, taking the entire line as a single argument, inserting it in arguments for each occurrence of replstr.

And it doesn't say anything about the interaction with the -n and -d options, so they're free to do whatever they please.

This is how it is on an (older) FreeBSD, less unexpected but non-standard:

fzu$ echo a b c d f g | xargs -I {} -n 2 echo {} LAST
a b LAST
c d LAST
f g LAST
fzu$ echo a b c d f g | xargs -I {} -n 1 echo {} LAST
a LAST
b LAST
c LAST
d LAST
f LAST
g LAST

Tags:

Xargs