On 2019-08-31 at 09:02, Roberto C. Sánchez wrote: > On Sat, Aug 31, 2019 at 08:39:56AM -0400, The Wanderer wrote:
>> Or perhaps >> >> sed 's/config=.*$/config=/g' >> >> ? >> >> Less elegant and idiomatic, but could also get the job done. >> > OK. > >> The 'g' at the end is in case there can be multiple occurrences of >> 'config=' in a single file, so that sed won't stop after the first >> one it finds. >> > That's not how 'g' works. It is global replace of all occurences of > the patter in the pattern space. By default, sed operates one line > at a time so the replacement will happen on every line that matches > the pattern even without the 'g'. <snip> > Since the desired effect is "replace everything to the end of the > line" then the 'g' has no practical effect. It is not really > possible to have multiple patterns match to the end of the line, > unless you were trying to do some form of relucant matching. Huh. In that case, apparently every explanation of the 'g' (and of the behavior without it) I've ever found and bothered to read has been confusing and misleading. I mean, I can easily believe that, I just didn't expect it. >> In practice, I'd either use this with 'sed -i [the above >> expression] filename' or (more likely) with 'cat filename | sed >> [the above expression] > newfilename'. >> >> (Yes, that's technically a "senseless use of cat". I do it anyway, >> because always using pipes at every stage makes it easy to add or >> remove filtering stages without having to adjust the syntax in >> another part of the pipeline, and because it's easier to stick with >> that habitual pattern than to change it up in the relatively few >> cases where I can be sure that multiple stages aren't and won't be >> needed.) >> >> (And may I say that it's annoying to need to explain this every >> time, in order to forestall being called out for "senseless use of >> cat"? Not that I get called out for that here very much, but it >> does seem to happen virtually every time I don't include an >> explanation...) > > You can avoid cat with something like this: <snip examples> > 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. 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. 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. 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. 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. > $ 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 |' ? 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. -- The Wanderer The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man. -- George Bernard Shaw
signature.asc
Description: OpenPGP digital signature