1

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

假设我要替换:

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

和:

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

我应该使用sed吗?我认为由于/并且[ ]我得到了奇怪的结果......

解决这个问题的最佳方法是什么?

4

4 回答 4

4

带有 -p 选项的 Perl 几乎与 sed 一样工作,并且它的正则表达式具有 \Q (引号)开关:

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

在 Perl 中,您可以使用不同的标点符号来分隔表达式(在我的示例中为 s{...}{...})。

于 2012-04-09T02:29:26.333 回答
3

是的,您需要转义括号,转义斜杠或使用不同的分隔符。

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

也就是说,在使用正则表达式时,SGML 和 XML 实际上并不比HTML好。不要指望这会一概而论。

于 2012-04-09T01:05:40.693 回答
0

这应该足够了:

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


您还可以将/sed 中的分隔符更改为不同的字符,例如,,|%.

于 2012-04-10T17:28:24.037 回答
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 不支持非贪婪乘数(*?)。

于 2012-05-24T09:52:12.200 回答