替换两个 HTML 注释之间的文本

替换两个 HTML 注释之间的文本

一般来说,我对sed/和正则表达式的世界很陌生,并且一直在研究它们的用法,但一直在努力满足我的需求:awk

我有一个htm页面,有一个单行通知,需要使用用户输入的文本(通过 shell 脚本)在两个充当标签的注释之间进行更新,例如:

<!--BeginNoticeMSG-->NOTICE: This is a notice<!--EndNoticeMSG-->

然后,用户输入的文本(存储在变量中,我们称之为$NEWNOTICE)将需要替换标签之间的内容,因此有效:

<!--BeginNoticeMSG-->$NEWNOTICE<!--EndNoticeMSG-->

它将被插入到htm文件中(例如):

<!--BeginNoticeMSG-->This is a test notice<!--EndNoticeMSG-->

如何正确识别和替换标签之间的文本?

答案1

这是一个(相当)基本的食谱,只有按照指定的方式才能满足您的需求:

#!/bin/bash
REPLACEWITH="Your replacement text here"
STARTTAG="BeginNoticeMSG"
ENDTAG="EndNoticeMSG"
sed -E "s/(<\!\-\-$STARTTAG\-\->)(.*)(<\!\-\-$ENDTAG\-\->)/\1$REPLACEWITH\3/" -i target_file.html

如果输入不同,它会以多种不同的方式中断,特别是如果输入“标签”被中断为多行。

通常不建议使用正则表达式来处理 HTML 和 XML(我意识到这只是一条注释),但是...如果您的输入像本文中暗示的那样可靠,那么这种简单的方法可能会成功。

在这种情况下,我将标签的部分反向引用为\1\3(与正则表达式中的括号项目相关),以减少键入替换内容所需的文本量。

或者没有-E选项,并且没有反向引用:

#!/bin/bash
REPLACEWITH="Text to replace with here"
STARTTAG="BeginNoticeMSG"
ENDTAG="EndNoticeMSG"
sed -e "s/<\!\-\-$STARTTAG\-\->.*<\!\-\-$ENDTAG\-\->/<\!\-\-$STARTTAG\-\->$REPLACEWITH<\!\-\-$ENDTAG\-\->/" -i target_file.html

答案2

假设您在同一行上从未出现过多个通知(更准确地说,在同一行上从未出现过多次 of<!--BeginNoticeMSG-->或 of ):<!--EndNoticeMSG-->

sed -e "s&\(<!--BeginNoticeMSG-->\).*\(<!--EndNoticeMSG-->\)&\1$NEWNOTICE\2&"

如果开始和结束注释可能不同,您可以为它们编写正则表达式。

请注意,这仅在您确定$NEWNOTICE不包含\,&或换行符时才有效,因为否则这些字符将被解释为 sed 语法。

为了增强标点符号的鲁棒性,请改用 awk。

export NEWNOTICE
awk '{sub(/<!--BeginNoticeMSG-->.*<!--EndNoticeMSG-->/, "<!--BeginNoticeMSG-->" env[NEWNOTICE] "<!--EndNoticeMSG-->"); print}'

相关内容