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