5

Is it possible to use xargs to invoke a command so that the last argument of the command is fixed?

My attempt:

printf '%s\n' a b c d | xargs -I{} echo {} LAST

ends up doing

echo a LAST  
echo b LAST  
echo c LAST  
echo d LAST  

I want for xargs to invoke

echo a b c d LAST
#fit as many as you can but always finish wiht LAST

Is this possible to do, preferably in a portable way?

7
  • 1
    not as far as I known but at least cp, mv and ln commands havs a -t|--target-directory parameter that replace the last arg... – xenoid Sep 1 '18 at 13:29
  • 1
    Would you please shed more light on what you want. i mean revise the question and add more clarifications. In the current shape it is not clear! – user88036 Sep 1 '18 at 13:51
  • 1
    Also, the output of your command is empty lines. – user88036 Sep 1 '18 at 13:53
  • 1
    Your command still doesn't work! "xargs: LAST: No such file or directory" – user88036 Sep 1 '18 at 14:00
  • 1
    Yes! it didn't work . I use Centos 7 – user88036 Sep 1 '18 at 14:09
10

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
3
  • 3
    I can't help thinking there could be a more neutral way of phrasing this answer. It also feels odd to point out one OS in particular (Linux), when you seem to be of the opinion that it's the behaviour required by the standard that's at fault here. – ilkkachu Sep 1 '18 at 15:34
  • 1
    could you please explain why do we need to invoke sh again at the end of that command? – Carlos Mendoza Feb 9 '19 at 13:09
  • 2
    @CarlosMendoza if you mean the sh after the -c '...' that's not invoking anything it's just setting argv[0]/$0; you can replace it with argv0 or anything you like. Without it, the echo wouln't have echoed its 1st argument. To get the idea, try sh -c 'echo "$@"' argv0 1 2 3 without argv0. – mosvy Feb 9 '19 at 14:47
-2

Not with xargs (alone). If you have an item list of unpredictable length, how should xargs know from the beginning (= first element) which element would be the last one? You'll need some additional logics around it to separate the desired element from the others.

3
  • @ilkkachu: Then, please show how from the list a b c d LAST to get to four parameter lists a LAST, b LAST, c LAST, and d LAST by using xargs alone without the constant LAST being supplied by other means (as wrongly done above). If that is what the requestor wanted. – RudiC Sep 1 '18 at 21:23
  • I thought they wanted to go from a b c d to a b ... LAST, or such, with more than one of a, b, etc used by xargs for each command invocation. (one is easy, that's what -I does.) They did specify the LAST part in the xargs command (not in the printf feeding xargs), it's just that it doesn't work like that with -I (but does in FreeBSD xargs -J). But yeah, you're right in that I misread your intent, though technicallyxargs could read the whole input before processing, but that wouldn't be very efficient. – ilkkachu Sep 1 '18 at 22:29
  • Now that I reread the original request, I admit I may have misread it, so the base of my approach is gone... – RudiC Sep 1 '18 at 22:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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