From: Ben Bacarisse on 27 May 2010 15:37 pk <pk(a)pk.invalid> writes: > Ben Bacarisse wrote: <snip> >> sed -e '/^string1$/N' -e 's/^string1\nstring2$/string3\nstring4/' > > (nitpick) > That has a slight issue for inputs like > > string1 > string1 > string2 > etc. Ah, yes. I had a nagging feeling I was posting too fast without thinking the corner cases out. > so the canonical way, as per the sed FAQ is > > sed -e :a -e '$!N;s/^string1\nstring2$/string3\nstring4/;ta' -e 'P;D' > > and, since \n in the rhs isn't supported by all seds, it should then be > > sed -e :a -e '$!N;s/^string1\nstring2$/string3\ > string4/;ta' -e 'P;D' However, neither of these work for me: Script started on Thu 27 May 2010 20:20:56 BST $ cat eg string1 string2 xxxx string1 string2 xxxx $ sed -e :a -e '$!N;s/^string1\nstring2$/string3\ > string4/;ta' -e 'P;D' <eg string3 string4 xxxx string1 string2 xxxx I may have got some detail wrong. I'd investigate further except I find sed to be the closest thing to write-only code that I come across these days. (It's old age I am sure -- I used to be fine with TECO.) I think: sed -e '/^string1$/N' -e 's/^string1\nstring2$/string3\nstring4/;t' -e 'P;D' fixes the issue you pointed out, but it uses a default jump target. Is there such a things as bad sed style? :-) -- Ben.
From: pk on 28 May 2010 04:18 Ben Bacarisse wrote: >> sed -e :a -e '$!N;s/^string1\nstring2$/string3\ >> string4/;ta' -e 'P;D' > > However, neither of these work for me: > > Script started on Thu 27 May 2010 20:20:56 BST > $ cat eg > string1 > string2 > xxxx > string1 > string2 > xxxx > $ sed -e :a -e '$!N;s/^string1\nstring2$/string3\ >> string4/;ta' -e 'P;D' <eg > string3 > string4 > xxxx > string1 > string2 > xxxx Right, my bad. These should work: $ sed '$!N;s/^string1\nstring2$/string3\ string4/' -e 'P;D' eg string3 string4 xxxx string3 string4 xxxx $ sed '$!N;s/^string1\nstring2$/string3\ string4/;t' -e 'P;D' eg Basically the jump can be removed, or it can be to the end of the script. If the replacement does not overlap with the searched text, they are virtually equivalent. > I may have got some detail wrong. I'd investigate further except I find > sed to be the closest thing to write-only code that I come across these > days. (It's old age I am sure -- I used to be fine with TECO.) > > I think: > > sed -e '/^string1$/N' -e 's/^string1\nstring2$/string3\nstring4/;t' -e > 'P;D' This also works but I like it less (just personal taste). > fixes the issue you pointed out, but it uses a default jump target. Is > there such a things as bad sed style? :-) Some people on this list say that using sed for anything else than simple substitutions on the same line is bad, so we better stop it here :-) (although in most cases I agree with that because simpler alternatives exist)
From: Janis Papanagnou on 28 May 2010 04:30 pk wrote: > Ben Bacarisse wrote: > >>> sed -e :a -e '$!N;s/^string1\nstring2$/string3\ >>> string4/;ta' -e 'P;D' >> However, neither of these work for me: [...] > > Right, my bad. These should work: [...] > >> I may have got some detail wrong. I'd investigate further [...] [...] > > Some people on this list say that using sed for anything else than simple > substitutions on the same line is bad, so we better stop it here :-) > (although in most cases I agree with that because simpler alternatives > exist) That's interesting. When I read in this posting about the above mistakes done with sed, where the application here is something that still appears to me to be a simple substitution, I thought exactly about the suggestion not to use sed for anything more complex than substitution _on a single line_. Janis
From: Ben Bacarisse on 28 May 2010 06:08 pk <pk(a)pk.invalid> writes: > Ben Bacarisse wrote: <snip> >> I think: >> >> sed -e '/^string1$/N' -e 's/^string1\nstring2$/string3\nstring4/;t' -e >> 'P;D' > > This also works but I like it less (just personal taste). I think it goes a bit beyond taste. You version does not need a part of the target string to be repeated. That's clearly a Bad Thing for maintenance but the most of my sed commands are never maintained -- I use it mostly for one-offs. <snip> -- Ben.
From: Ed Morton on 28 May 2010 08:05 On 5/28/2010 3:18 AM, pk wrote: > Ben Bacarisse wrote: <snip> >> Is >> there such a things as bad sed style? :-) > > Some people on this list say that using sed for anything else than simple > substitutions on the same line is bad, so we better stop it here :-) Maybe it's just me, but I think this thread with it's many iterations of sed attempts: sed -e '{ N s/^string1\nstring2$/string3\nstring4/ }' sed -e '/^string1$/N' -e 's/^string1\nstring2$/string3\nstring4/' sed -e :a -e '$!N;s/^string1\nstring2$/string3\nstring4/;ta' -e 'P;D' sed -e :a -e '$!N;s/^string1\nstring2$/string3\ string4/;ta' -e 'P;D' sed -e '/^string1$/N' -e 's/^string1\nstring2$/string3\nstring4/;t' -e 'P;D' sed '$!N;s/^string1\nstring2$/string3\ string4/' -e 'P;D' each with arcane configurations of single-character commands and each attempting to solve non-obvious problems that the others have with some input sets, pretty well underscores the point that you shouldn't attempt to use sed to do anything with input that spans lines. I can't imagine coming across one of those commands and being able to tell what it does without some long, SERIOUS thought and reference to manual pages. The awk solution, on the other hand: awk -v RS= '{sub(/string1\nstring2/,"string3\nstring4")}1' is pretty clear and only took one attempt to get right. Ed.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: compare 10th column from file1 to file2 Next: aborting a bash script with control-c |