使用 sed 替换 XML 文件中的特殊字符字符串

使用 sed 替换 XML 文件中的特殊字符字符串

尽管我使用 grep 可以轻松找到相同的字符串,但我很难使用 sed 替换 XML 文件中的文本字符串。由于要替换的新字符串和旧字符串包含大量特殊字符,我认为最好将它们存储在变量中,而不是使用大量反斜杠:

OLD_STRING='<property name="webServiceHost">${jboss.bind.address}</property>'
NEW_STRING='<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'

字符串似乎按预期存储:

$ echo $OLD_STRING; echo $NEW_STRING
<property name="webServiceHost">${jboss.bind.address}</property>
<!--<property name="webServiceHost">${jboss.bind.address}</property>-->

通过 Grep 确认旧字符串存在于 XML 文件中:

$ grep "$OLD_STRING" jboss-beans.xml
<property name="webServiceHost">${jboss.bind.address}</property>

但是以下 sed 命令不产生任何输出:

sed -i 's/"$OLD_STRING"/"$NEW_STRING"/g' jboss-beans.xml

知道我这里遗漏了什么吗?

答案1

将 shell 变量放在单引号中会禁用它们的解释。这就是您的命令无效的原因。

$ echo  's/"$OLD_STRING"/"$NEW_STRING"/g'
s/"$OLD_STRING"/"$NEW_STRING"/g

应该这样写:

sed -i "s/'$OLD_STRING'/'$NEW_STRING'/g" jboss-beans.xml

但随后变量被解释调用sed并且再次包含特殊字符:

$ echo  "s/'$OLD_STRING'/'$NEW_STRING'/g"
s/'<property name="webServiceHost">${jboss.bind.address}</property>'/'<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'/g

因此,sed有这个特殊功能允许s///通过简单地使用命令分隔符来定义命令分隔符,例如:

sed -i "s#'$OLD_STRING'#'$NEW_STRING'#g" jboss-beans.xml

但是您的搜索表达式包含特殊的正则表达式字符,这样使用sed只是浪费它的能力。我会像这样写表达式:

sed -i 's/\(<.*webServiceHost.*jboss.bind.address.*>\)/<!--\1-->/' jboss-beans.xml

当然,您可以根据需要使匹配字符串更具体或更不具体。还有其他不错的功能可以提供帮助。sed允许将编辑操作缩小到与特定模式匹配的行。您的命令可能如下所示:

sed -i '/webServiceHost/ s/^\(.*\)$/<!--\1-->/' jboss-beans.xml

答案2

这可能对你有用:
命令行 XML 操作
http://xmlstar.sourceforge.net/

AFAICR
apt-get 安装 xmlstarlet

相关内容