2012-04-09 221 views
1

我需要在一个小bash脚本内替换文件内的字符串,但是...我得到奇怪的结果。从bash脚本中替换文件中的字符串

比方说,我想替换:

<tag><![CDATA[text]]></tag> 

有了:

<tag><![CDATA[replaced_text]]></tag> 

我应该使用sed?我认为由于/[]我越来越奇怪的结果...

接触这个最好的方法是什么?

回答

3

是的,你需要跳过括号,并且要么跳过斜杠或使用不同的分隔符。

sed 's,<tag><!\[CDATA\[text\]\]></tag>,<tag><!\[CDATA\[replaced)text\]\]></tag>,' 

这就是说,SGML和XML实际上没有任何比HTML当谈到使用正则表达式;不要期望这个概括。

4

Perl,以-p选项的作品几乎一样SED,它有它的正则表达式\ Q(报价)开关:

perl -pe 's{\Q<tag><![CDATA[text]]></tag>} 
      {<tag><![CDATA[replaced_text]]></tag>}' YOUR_FILE 

而且在Perl中,你可以使用不同的标点符号分隔符你的表情(S {.. 。} {...}在我的例子中)。

+1

对于'\ Q'为+1。要结束引用,请对文字字符串使用'\ E' – Gowtham 2012-04-10 17:57:47

+0

+1。如果有人链接到如何逃避原始或替换文本以避免嵌入式出现'\ E'或其他特殊序列,这将更加优秀。 – l0b0 2012-04-11 10:04:01

0

这应该是足够了:

$ echo '<tag><![CDATA[text]]></tag>' | sed 's/\[text\]/\[replaced_text\]/' 
<tag><![CDATA[replaced_text]]></tag> 


你也可以改变你的/分离器内的sed到不同的性格像,|%

0

只需使用比/以外的分隔符,在这里我使用#:

sed -i 's#<tag><!\[CDATA\[text\]\]></tag>#<tag><![CDATA[replaced_text]]></tag>#g' filename 

-i拥有的,而不是打印出来的sed变化的文件。 g用于匹配不止一次(全局)。

但是你知道你想要匹配的确切字符串,标签和文本吗? 举例来说,如果你要替换所有与你replaced_text文字:

perl -i -pe 's#(<tag><!\[CDATA\[)(.*?)(\]\]></tag>)#\1replaced_text\3#g' filename 

切换到perl,因为sed的不支持非贪婪乘数(在*?)。