On Sat, Aug 31, 2019 at 09:26:49AM -0400, The Wanderer wrote: > On 2019-08-31 at 09:02, Roberto C. Sánchez wrote: > > > The only time you need to change the syntax is to add something > > before sed. But then, that's why shells have I/O redirection: > > > > (sed 's/config=.*$/config=/g' | tr -d '=') <~/test.txt > > >~/other_test.txt > > This is *far* more complicated and messy, both syntactically and to type > in, than just having cat at the beginning of a pipeline. > That's quite a stretch.
Your way: cat ~/test.txt | sed 's/config=.*$/config=/g' | tr -d '=' >~/other_test.txt A better way: (sed 's/config=.*$/config=/g' | tr -d '=') <~/test.txt >~/other_test.txt The better way is actually simpler. It places all the logic for what is happening at the start of the line and the I/O redirection (which is basically just fluff) to the right. Your way requires that I look at it for several moments to separate the I/O supporting pieces from the actual interesting command logic. The better way has a clean visual separation. > It also loses an important benefit when building and tweaking such > pipelines by hand: convenience of editing. In most shells with which I > have any experience, command history will place the cursor at the end of > the remembered line. > So, get a better shell? > The further from the rightmost position the part you want to edit is, > the less convenient it is to do that editing, especially when doing > multiple trial-and-error passes to figure out what syntax will actually > produce the desired result. > Again, it sounds like a better shell is in order. > One item to the right of the final command (either redirection to a > file, or pipe to a pager) is usually unavoidable, at least with output > of any noticeable size; depending on your shell, there may be > keybindings for quick movement along the command line which reduce the > inconvenience again. > Here is an alternative that places the interesting commands as far to the right as possible: $ i=~/test.txt; o=~/other_test.txt; (sed 's/config=.*$/config=/g' | tr -d '=') <${i} >${o} $ cat other_test.txt Test config Test config Test config That minimizes the distance between the end of the processing command pipeline and the end of the line. You can add spaces before and/or after ';', '(', and ')' to create more explicit word boundaries if you like. > But having to jump back several stages along the command line, and not > even to a point which is at the edge of a 'word' according to what (at > least) the keybindings I'm familiar with recognize, is IMO not worth the > tradeoff vs. saving a single process per invocation. > You'll notice that it's not about saving a process. The better way involves a subshell '()' which will create a new process. > > $ cat ~/other_test.txt > > Test config > > Test config > > Test config > > > > Now I can add pipe stages within the sub-shell to my hearts content > > and I can even do other things like replace "<~/test.txt" with > > "<$(some other command that queries a database)" so that the input > > does not even need to come from a real file. > > Isn't it just as easy to replace 'cat test.txt |' with 'some other > command that queries a database |' ? > It is just as easy. However, 'cat' is not a value-added part of the processing pipeline. So, why have it at all? > And that approach preserves the intuitiveness of having the input be > specified at the start of the command line, and the output at the end, > instead of the input and the output both being specified at the end. > What is intuitive is not always right or best. It is better to properly learn the features and functions of the shell or other environment so that proper separation can be made between business logic and supporting structures. If the command being worked on ends up in a script it is much easier to make the better form I suggested readable and maintainable than it is with the more 'intuitive' version. Regards, -Roberto -- Roberto C. Sánchez