2016-11-22 93 views
0

说我有这样一段文字:与线的右侧部分下划线替换点

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

我想下面的结果在右边部分用下划线代替点(在{{}}之间后分隔符):

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

我在寻找合适的正则表达式来执行一个班轮sed command`更换。

我在这一个领先:https://regex101.com/r/8wsLHo/1,但它捕获所有的点,包括左边的那些,我不想要的。 我想这种变化,以排除那些在左边的一部分,但随后它并不再捕获任何:https://regex101.com/r/d7WAmX/1

+0

您的分隔符是'{{'和'}}',所以我认为您的文本中可以包含单个的{{或'}'字符。 'some.blah.key = {{abc {def} ghi}}',对吧?你应该在你的示例输入/输出中包含它,否则当发生这种情况时你会得到失败的解决方案。 –

回答

4

您可以使用一个循环:

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

:a定义了一个标签“ a“
ta当某物被替换时跳转到”a“。

+2

一个非常聪明的解决方案。 – Cyrus

+0

@Cyrus:谢谢<°))))))))> –

+0

我和它一起玩,把它剥下来。替换(使用GNU sed)到'=':'sed -r':a; s /(=。*)\ ./ \ 1 _ /; ta'文件'和'=':'sed左边-r':a; s/\。(。* =)/ _ \ 1 /; ta'文件' – Cyrus

2

我想出了这个相当复杂的一行代码:

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

解释:

  • h:在保持缓冲放线
  • s/=.*/=/:揍右侧后=
  • x:交换摆在主缓冲区再次行,第一部分在保持缓冲
  • s/.*=//:以前=
  • s/\./_/g撞地留下部分:执行替换现在的点,有在主缓冲区只有右侧部分
  • H :追加主缓冲区来保存缓冲
  • x:交换再次
  • s/\n//缓冲器:移除换行或两个部分出现在不同的行

,这是很有趣,但也许sed是不执行该操作的最佳工具,这恰恰属于code golf