Hacker News new | ask | show | jobs
by yuchi 4177 days ago
Do someone know how to run a command for every line emitted in a unix pipe? I tried the oneliner in the linked story using Mac OS X’s `say`, but it doesn’t work with pipes.
5 comments

In a typical UNIX fashion, there's a program that runs programs:

  ping 127.0.0.1 | sed -e 's/.*/ping/' | xargs -d'\n' -n1 say
-d is a GNU extension, won't work on OSX (short of having installed and running GNU xargs), and it's not needed either in this case.

And `sed -e <command>` is redundant, `-e` is used to specify multiple commands.

xargs -n1 (-n is so it executes the command for each input)

You'll also need sed -l to limit buffering.

    ping <host> | sed -l 's/.*/ping/' | xargs -n1 say
perfect!

  cat input |while read a; do do_something_with $a; done
thank you so much!
ping goodhost | sed -l 's/.*/ping/' | while read line; do echo $line | say; done
Bit of a tangent, but using the voice "Tom" on OS X, saying "ping" says "pling" instead. Fine with other voices but rather curious.
You might want to use "--unbuffered" flag in sed execution.
that option appears to be gnu-specific. -l should make it line-buffered
Note that -l is also an extension, just a BSD one.

The only options in POSIX sed are -e, -f and -n (and -e is usually cargo-culted by people who want -E. -E being a BSD extension enabling extended regular expressions — -r in GNU sed)