(xargs foo | grep bar | sort | wc -l) < file
It makes the pipeline one command, both lexically (verb comes first) and concretely (the pipeline is kicked off in a subshell) (xargs foo | grep bar | sort | wc -l) < file
It makes the pipeline one command, both lexically (verb comes first) and concretely (the pipeline is kicked off in a subshell) verb file
cat file | verb1 | verb2 | verb3
(verb1 | verb2 | verb3) < file
verb123 file
EDIT: Consider the calling conventions, which one of these handles it's arguments differently? Assume that verb123 is an equivalent to the pipeline -- the subshell+stdin construction lends itself to shell aliases: alias verb123="(verb1 | verb2 | verb3) < "Of course, with the usual argument vs stdin conventions, either of the middle two could also be rewritten:
verb1 file | verb2 | verb3
This is probably how I'd write such a chain. (wc Lines) . sort . (grep "bar") . (xargs "foo") =<< file
But note in this case that all the data "flows in the same direction". wc Lines $ sort $ grep "bar" $ xargs "foo" =<< file Prelude> :info $
($) :: (a -> b) -> a -> b -- Defined in GHC.Base
infixr 0 $
Prelude> :info =<<
(=<<) :: (Monad m) => (a -> m b) -> m a -> m b
-- Defined in Control.Monad
infixr 1 =<<
Prelude> :info .
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in GHC.Base
infixr 9 .
Incidentally, the parens in my example are actually unnecessary. Function application is about 10, and (.) is 9.It's too easy to make a mistake and type >
..and that can ruin your whole day.
I find that to be a far more pernicious design error -- they should have made the longer token the destructive one, or used another character in it.
The point is a logical improvement anyway (not burying the input argument near the beginning). I'm kind of surprised that the bash folks haven't turned cat into a builtin like they did with time and some of the other coreutils.
It's too bad it's about 30 years too late to stem the tide of shit like cat -v: http://harmful.cat-v.org/cat-v/
Here's cat as a pure sh builtin:
shcat {
for arg in "$@"; do
exec 3<>"$arg"
while read line <&3; do
echo "$line"
done
exec 3>&-
done
}
The shell by it's very nature can't just do exactly one task well, it's a programmable environment for living in. The cancer that's bloating UNIX was the way that the BSD and especially the GNU crews took simple tools and cross-pollinated them randomly with stupid shit. Try running "/bin/true --help" on a GNU system sometime -- there's a damn good reason why "your shell may have its own version of true". % /bin/true --help
Usage: /bin/true [ignored command line arguments]
or: /bin/true OPTION
Exit with a status code indicating success.
--help display this help and exit
--version output version information and exit
NOTE: your shell may have its own version of true, which usually supersedes
the version described here. Please refer to your shell's documentation
for details about the options it supports.
Report bugs to <bug-coreutils@gnu.org>.
I wouldn't necessarily call that 'bloated' unless you feel that any program that uses one bit more than absolutely necessary should be scrapped as 'bloated beyond belief.'> there's a damn good reason why "your shell may have its own version of true".
Because why exactly?
xargs foo < file | grep bar | sort | wc -l