News for hackers. Stuff that matters.
Re:For the Love of Pipes by msla on Tuesday January 22, 2019 @10:25AM (#18968884)
I find something like this:

   grep '^x' < input | sed 's/foo/bar/g' 
to be very readable, as the flow is still visually apparent based on punctuation.
Re:For the Love of Pipes by OskarS on Tuesday January 22, 2019 @11:12AM (#18969296)
I don't like this style at all. If you're following the pipeline, it starts in the middle with "input", goes to the left for the grep, then to the right (skipping over the middle part) to sed.

     cat input | grep '^x' | sed 's/foo/bar/g'
Is far more readable, in my opinion. In addition, it makes it trivial to change the input from a file to any kind of process.

I'm STRONGLY in favor of using "cat" for input. That "useless use of cat" article is pretty dumb, IMHO.

Re:For the Love of Pipes by dearrifling on Tuesday January 22, 2019 @12:02PM (#18969808)
Note that '<input grep | foo' is also valid.
Re:For the Love of Pipes by kps on Tuesday January 22, 2019 @04:10PM (#18972506)
In this particular example, ‘unnecessary use of cat’ is accompanied by ‘unnecessary use of grep’.

    cat input | grep '^x' | sed 's/foo/bar/g'
→

    sed '/^x/s/foo/bar/g' <input
Re:For the Love of Pipes by irishsultan on Wednesday January 23, 2019 @09:06AM (#18978168)
That's not the same thing. The sed output will still keep lines not starting with x (just not replacing foo with bar in those) where grep will filter those out.
Re:For the Love of Pipes by kps on Wednesday January 23, 2019 @11:03AM (#18979358)
Yeah, Muphry's law at work. Corrected version:

   sed -n '/^x/s/foo/bar/gp' <input
This may be an inadvertent argument for the ‘connect simpler tools’ philosophy.
Re:For the Love of Pipes by sigjuice on Tuesday January 22, 2019 @12:21PM (#18970052)
You can just remove the <
Re:For the Love of Pipes by msla on Tuesday January 22, 2019 @12:22PM (#18970064)
You can if input is a file. It might be a program with no arguments or something else.
Re:For the Love of Pipes by sigjuice on Tuesday January 22, 2019 @12:28PM (#18970153)
In your original command, how can 'input' be a program with no arguments?
Re:For the Love of Pipes by msla on Tuesday January 22, 2019 @01:04PM (#18970538)
Oh, damn. You're exactly right.

OK, to save some of my face, this will work:

    grep 'foo' <(input) | sed 's/baz/bar/g'
... at least in zsh and probably bash.
Re:For the Love of Pipes by laumars on Tuesday January 22, 2019 @03:09PM (#18971928)
I don’t like that at all. That creates a subshell and is also less readable than

    input | grep foo | sed ...
Re:For the Love of Pipes by msla on Tuesday January 22, 2019 @05:08PM (#18973080)
That specific example is less readable, but I do like being able to do this:

    diff <(prog1) <(prog2)
and get a sensible result.

And sometimes programs just refuse to read from stdin but do just fine with an unseekable file on the command line. True, you do have this:

    input | recalcitrant_program /dev/stdin
... but it's a bit of a tossup as to which one's more readable at this point. They're both relying on advanced shell functionality.
Re:For the Love of Pipes by laumars on Tuesday January 22, 2019 @06:31PM (#18973926)
> That specific example is less readable, but I do like being able to do this:

> diff <(prog1) <(prog2)

> and get a sensible result.

That is called process substitution and is exactly the kind of use case that it's designed for. So yes, process substitution does make sense there.

> input | recalcitrant_program /dev/stdin

> ... but it's a bit of a tossup as to which one's more readable at this point. They're both relying on advanced shell functionality.

There's no tossup at all. Process substitution is easily more readable than your second example because you're honouring the normal syntax of that particular command's parameters rather than kludging around it's lack of STDIN support.

Also I wouldn't say either example is using advanced shell functionalities either. Process substitution (your first example) is a pretty easy thing to learn and your second example is just using regular anonymous pipes (/dev/stdin isn't a shell function, it's a proper pseudo-device like /dev/random and /dev/null) thus the only thing the shell is doing is the same pipe described in this threads article (with UNIX / Linux then doing the clever stuff outside of the shell).