48

How can I make the second echo to echo out test in this example as well:

 echo test  | xargs -I {} echo {} && echo {}
2
  • var=test & echo $var ...
    – alexus
    Mar 2, 2016 at 14:38
  • xargs -I {} var={} echo $var && echo $var That would give you: No such file or directory.
    – defiler
    Mar 2, 2016 at 14:47

3 Answers 3

59

Just write {} two times in your command. The following would work:

$ echo test | xargs -I {} echo {} {}
test test

Your problem is how the commands are nested. Lets look at this:

echo test | xargs -I {} echo {} && echo {}

bash will execute echo test | xargs -I {} echo {}. If it runs successfully, echo {} is executed. To change the nesting, you could do something like this:

echo test | xargs -I {} sh -c "echo {} && echo {}"

However, you could get trouble because the approach might be prone to code injection. When "test" is substituted with shell code, it gets executed. Therefore, you should probably pass the input to the nested shell with arguments.

echo test | xargs -I {} sh -c 'echo "$1" && echo "$1"' sh {}
3
  • 3
    Note that you will get unexpected results in your last code if you have afile callod, literally, $(rm -f *). It's better to do xargs -I {} sh -c 'echo "$1" && echo "$1"' sh {}
    – Kusalananda
    May 7, 2019 at 20:04
  • @Kusalananda, thanks. I was aware of the problem but I could not think of a simple solution at that moment. I integrated your suggestion into the answer.
    – JojOatXGME
    May 12, 2019 at 13:19
  • This is the real answer right here. If all you're doing is using echo then yeah just use echo {} {} but I think OP did that as a easy demonstration. In our case, we're redirecting the output to a file and using sh -c did the trick perfectly. Thanks! Jun 17, 2021 at 19:14
11

Another option is to use -i flag, which is the same as -I{} (it implies that the replacement is given with {}):

$ echo test | xargs -i echo {} {}
1
  • 4
    In the meantime: This option is deprecated; use -I instead. has been added to the manual man xargs. Mar 25, 2019 at 17:29
0

For me only the lower case works. I had hundreds of images in a directory and wanted to get them sources into a list. Upper case i -I option did not work for me. Only the lower case. Probably due to version differences. These images all had names like Daniel_(somenumber).jpg.

This syntax has worked :

ls -l | tr -s ' ' ':'| cut -d: -f9 | xargs -i echo "img src='"{}"'alt='{}'"

Returns:

src='Daniel_248.jpg' alt='Daniel_248.jpg'
...

Linux ver 4.14.96-hw+ #80 SMP x86_64 GNU/Linux

2
  • 2
    I added some formatting to your answer to make it more readable. I hope I have correctly understood it.
    – fra-san
    May 7, 2019 at 19:35
  • I think there are at least 1 or 2 double quotes (") missing at the end of the echo expression... FYI on macOS, I resorted to this simpler command: ls -1 | xargs -I {} echo "img src='{}' alt='{}'"
    – maxxyme
    Apr 7, 2022 at 11:53

You must log in to answer this question.