Maybe, but there are a couple of different kinds of "things" here: the actual primitive operations, and the techniques available for combining and coordinating them. For example, the `sort` program can only be told to sort based on certain specific analyses of the line contents (like extracting a certain "field" and converting that string to integer); it can't be supplied with a higher-order function. While things like `tee` exist, it isn't really practical to treat part of the pipeline as a reusable abstraction, except perhaps by writing a file (which leads to the author's approach with temporary files and `join`). And of course you're stuck with constant serialization and deserialization between processes.
https://news.ycombinator.com/item?id=49600275 is a great illustration of how to use Bash's "means of combination" more effectively than what OP thought of doing. But notice that it still relies on decorate-sort-undecorate for keyed sorting, and not only that but the undecoration has to be deferred until after `uniq` has made use of it, in a way that magically collapses the first decoration into something that can be used for a second sort, while adding a second decoration (the count). And then it still needs postprocessing because you can't express control over the structure of the decoration (there isn't really any, it's just string concatenation, but I mean you don't even control the order in which the pieces are concatenated).