简体   繁体   English

从 bash 脚本替换文件中的字符串

[英]Replace string within a file from a bash script

I need to replace within a little bash script a string inside a file but... I am getting weird results.我需要在一个小的 bash 脚本中替换一个文件中的字符串但是......我得到了奇怪的结果。

Let's say I want to replace:假设我要替换:

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

With:和:

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

Should I use sed ?我应该使用sed吗? I think due to / and [ ] I am getting weird results...我认为由于/[ ]我得到了奇怪的结果......

What would be the best way of approaching this?解决这个问题的最佳方法是什么?

Perl with -p option works almost as sed and it has \Q (quote) switch for its regexes:带有 -p 选项的 Perl 几乎与 sed 一样工作,并且它的正则表达式有 \Q(引号)开关:

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

And in Perl you can use different punctuation to delimiter your expressions (s{...}{...} in my example).在 Perl 中,您可以使用不同的标点符号来分隔您的表达式(在我的示例中为 s{...}{...})。

Yes, you need to escape the brackets, and either escape slashes or use different delimiters.是的,您需要转义括号,转义斜线或使用不同的定界符。

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

That said, SGML and XML are not actually any better than HTML when it comes to using regexes;也就是说,在使用正则表达式方面,SGML 和 XML 实际上并不比HTML好多少; don't expect this to generalize.不要指望这会一概而论。

This should be enough:这应该足够了:

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


You can also change your / separator inside sed to a different character like , , |您还可以将 sed 中的/分隔符更改为不同的字符,例如, , | or % .%

Just use a delimiter other than /, here I use #:使用/以外的分隔符即可,这里我使用#:

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

-i to have sed change the file instead of printing it out. -i让 sed 更改文件而不是打印出来。 g is for matching more than once (global). g用于多次匹配(全局)。

But do you know the exact string you want to match, both the tag and the text?但是你知道你想要匹配的确切字符串,包括标签和文本吗? For instance, if you want to replace the text in all with your replaced_text:例如,如果你想用你的 replaced_text 替换所有的文本:

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

Switched to perl because sed doesn't support non-greedy multipliers (the *?).切换到 perl,因为 sed 不支持非贪婪乘法器(*?)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM