2016-12-25 128 views
0

我一直在試圖做一個sed替換。出於某種原因,我不能我的頭周圍sed和正則表達式(這是我第二次中美戰略經濟對話的問題)查找前後替換字符串

基本上我想找到並替換文本然後找一些文本的下一次出現並取代

到目前爲止,我有這個

echo "This could be anywhere and this bit should be changed \$\{hcvar-BookName\} and this would remain" | sed 's/$\\{hcvar-/" + hcvar-/g' 

這將返回:

*This could be anywhere and this bit should be changed " + hcvar-BookName\} and this would remain* 

不過,我想回到

*This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain* 

這將取代}與+「

的邏輯是這樣的:

Find: \$\{hcvar- 
Replace with: " + hcvar- 
Then find the next occurrence of: \} 
Replace with: + " 

第二位,以取代將是包含字符串之後:hcvar-

這應該適用於以下字符串的例子

  • 這可能是任何地方,此位應改變 \ $ {hcvar-BOOKNAME},這將保持
  • 這可能是任何地方, 此位應改爲\ $ {hcvar-somethingelse},這將 保持
  • 這可能是任何地方,此位應改變
    \ $ {hcvar-wouldnevercontainspaces},這將保持

任何幫助,將不勝感激。

回答

0

你需要用反斜槓逃逸$:

echo "This could be anywhere and this bit should be changed \$\{hcvar-BookName\} and this would remain" | sed -e 's/\$\\{hcvar-/" + hcvar-/g' -e 's/\\}/ +/'

輸出:

This could be anywhere and this bit should be changed " + hcvar-BookName + and this would remain

+0

在POSIX sed的'$'如果它不是替換命令的'pattern'部分中的最後一個字符,則爲文字。在許多方面,如果它是最後一個邏輯字符,'$'不會是字面的,即:'s/\(a \ | $ \)/ b /'將會替換'a'或空字節, B'。 – andlrc

1

假設你輸入居然是:

... changed ${hcvar-BookName} and ... 

那麼下面將工作:

$ sed 's/${\([^}]*\)}/" + \1 + "/' file.txt 
This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain 

注意使用單引號來保存,否則這將是特殊字符的外殼:

$ echo '...changed ${hcvar-BookName} and ...' | sed '...' 

如果輸入的是不實際使用\{我。E:... $\{hello\} ...,那麼這可能會奏效:

$ sed 's/$\\{\([^}]*\)\\}/" + \1 + "/' file.txt 
This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain 

擊穿:

s/   /  /# Replace ... with ... 
    ${   }    # Literal ${ and literal } 
    \( \)    # \(and \) is a capturing group 
     [^}]*    # Match everything but } zero or more times 
       " + \1 + " # \1 will be expanded to the captured result 
          # from \(, \). The rest is literal 

添加g葉形的,如果您需要在每一行乘換人:

s/pattern/replacement/g 
#     ^Global flag