16

for exmaple, using the command

cat foo.txt | xargs -I{} -n 1 -P 1 sh -c "echo {} | echo"

The foo.txt contains two lines

foo
bar

The above command print nothing.

Ryan
  • 5,341
  • 21
  • 71
  • 87

2 Answers2

6
cat foo.txt | xargs -J % -n 1 sh -c "echo % | bar.sh" 

Tricky part is that xargs performs implicit subshell invocation. Here sh invoked explicitly and pipe not becomes the part of parent conveyor

Kondybas
  • 6,864
  • 2
  • 19
  • 24
  • 1
    Thanks, I have updated my question to provide a more concret example. but it does not work as you suggested.. – Ryan Dec 24 '13 at 09:13
  • 1
    echo cant read from stdin, so piping to it has no sense. compare this: `cat foo.bar | wc -l` and `cat foo.bar | xargs -J % -n 1 sh -c "echo % | wc -l"` – Kondybas Dec 24 '13 at 09:50
  • 1
    I think you mean `-I` instead of `-J`; there is no `-J` option to xargs – Hitechcomputergeek Jun 01 '17 at 02:18
  • @Hitechcomputergeek FreeBSD's version of `xargs` have `-J` option that is equivalent to the `-i` of the linux `xargs` – Kondybas Jun 01 '17 at 13:15
  • @Kondybas Thanks for telling me that; I was not aware that there was a difference between the two. You can trust GNU to not follow POSIX lol. (`-J` isn't defined in POSIX but `-I` is and has a different use than GNU's.) – Hitechcomputergeek Jun 01 '17 at 13:59
  • `-J` can take multiple inputs as multiple arguments. `-I` is one command per line. Try doing `seq 10 | xargs -J % echo %` vs `seq 10 | xargs -I % echo %` and you will see. `-J % -n 1` is similar to `-I` but [`-n` splits on whitespace](https://stackoverflow.com/questions/41623959/what-is-the-difference-between-l-and-n-in-xargs/49713754#49713754). `-J % -L 1` is equivalent to `-I`. – dosentmatter Mar 14 '19 at 22:14
2

If you want to process all the lines of foo.txt you will have to use a loop. Use & to put the process to background

while read line; do
   echo $line | bar.sh &
done < foo.txt

If your input contain spaces temporarily set the internal field separator to the newline

# save the field separator
OLD_IFS=$IFS

# new field separator, the end of line 
IFS=$'\n'

for line in $(cat foo.txt) ; do
   echo $line | bar.sh &
done

# restore default field separator  
IFS=$OLD_IFS     
Matteo
  • 457
  • 3
  • 14