On Sat, Aug 31, 2019 at 08:39:56AM -0400, The Wanderer wrote:
> On 2019-08-31 at 07:58, Roberto C. Sánchez wrote:
> 
> > On Sat, Aug 31, 2019 at 01:49:20PM +0200, Computer Planet wrote:
> > 
> >> Hi guys! Is It possible, with "sed" erase all after a pattern? I'm
> >> trying in all way but I can't... I'd like to erase all after the
> >> pattern "config=" but only in the same line, regardless of where it
> >> is located inside in a file.
> >> 
> >> Can somebody help me please? Thank in advance for reply.
> >> 
> >> e.g.: after "config=" erase all until the end of the line
> > 
> > Something like this:
> > 
> > sed -E 's/(.*config=).*/\1/'
> 
> 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'.

$  cat ~/test.txt 
Test config=foo
Test config=foo
Test config=foo
$  sed 's/config=.*$/config=/g' ~/test.txt 
Test config=
Test config=
Test config=
$  sed 's/config=.*$/config=/' ~/test.txt 
Test config=
Test config=
Test config=

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.

> 
> 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:

sed [expr] filename > newfilename

To add more sed expressions:

sed -e [expr1] -e [expr2] filename > newfilename

To add something after sed:

sed -e [expr1] -e [expr2] filename | othercmd > newfilename

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

$ 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.

Regards,

-Roberto

-- 
Roberto C. Sánchez

Reply via email to