47

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

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

3 Answers3

58

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
    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 07 '19 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 '19 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! – Joshua Pinter Jun 17 '21 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 {} {}
Omer Dagan
  • 533
  • 6
  • 17
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

fra-san
  • 10,205
  • 2
  • 22
  • 43
  • 2
    I added some formatting to your answer to make it more readable. I hope I have correctly understood it. – fra-san May 07 '19 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 07 '22 at 11:53