1

Say I have this piece of text:

some.blah.key={{blah.woot.wiz}}
some.another.foo.key={{foo.bar.qix.name}}
+ many other lines with a variable number of words separated by dots within {{ and }}

I'd like the following outcome after replacing dots with underscores in the right part (between the {{ and }} delimiters):

some.blah.key={{blah_woot_wiz}}
some.another.foo.key={{foo_bar_qix_name}}
...

I'm looking for the appropriate regex to perform the replacement in a one-liner sedcommand`.

I'm on a lead with this one: https://regex101.com/r/8wsLHo/1 but it capture all dots, including those on the left part, which I don't want. I tried this variation to exclude those on the left part but then it doesn't capture anything anymore: https://regex101.com/r/d7WAmX/1

Cache Staheli
  • 3,510
  • 7
  • 32
  • 51
  • Your delimiters are `{{` and `}}` so I assume you can have individual `{` or `}` chars within your text, e.g. `some.blah.key={{abc { def } ghi}}`, right? You should include that in your sample input/output or you'll get solutions that fail when that occurs. – Ed Morton Nov 23 '16 at 02:34

2 Answers2

4

You can use a loop:

sed ':a;s/\({{[^}]*\)\./\1_/;ta' file

:a defines a label "a"
ta jumps to "a" when something is replaced.

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
2

I came up with this quite complex one-liner:

sed "h;s/=.*/=/;x;s/.*=//;s/\./_/g;H;x;s/\n//"

explanations:

  • h: put line in hold buffer
  • s/=.*/=/: clobber right part after =
  • x: swap to put line in main buffer again, first part in hold buffer
  • s/.*=//: clobber left part before =
  • s/\./_/g: perform replacement of dots now that there's only right part in main buffer
  • H: append main buffer to hold buffer
  • x: swap buffers again
  • s/\n//: remove linefeed or both parts appear on separate lines

that was quite fun, but maybe sed is not the best tool to perform that operation, this rather belongs to code golf

Community
  • 1
  • 1
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219