2016-11-22 69 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