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

rol*_*rok 6 linux sed find-and-replace special-characters

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

OLD_STRING='<property name="webServiceHost">${jboss.bind.address}</property>'
NEW_STRING='<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'
Run Code Online (Sandbox Code Playgroud)

字符串似乎按预期存储:

$ echo $OLD_STRING; echo $NEW_STRING
<property name="webServiceHost">${jboss.bind.address}</property>
<!--<property name="webServiceHost">${jboss.bind.address}</property>-->
Run Code Online (Sandbox Code Playgroud)

Grep'ing 确认旧字符串存在于 XML 文件中:

$ grep "$OLD_STRING" jboss-beans.xml
<property name="webServiceHost">${jboss.bind.address}</property>
Run Code Online (Sandbox Code Playgroud)

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

sed -i 's/"$OLD_STRING"/"$NEW_STRING"/g' jboss-beans.xml
Run Code Online (Sandbox Code Playgroud)

知道我在这里缺少什么吗?

Raj*_*ish 3

将 shell 变量放在单引号中会禁用它们的解释。这就是为什么你的命令没有效果。

$ echo  's/"$OLD_STRING"/"$NEW_STRING"/g'
s/"$OLD_STRING"/"$NEW_STRING"/g
Run Code Online (Sandbox Code Playgroud)

应该这样写:

sed -i "s/'$OLD_STRING'/'$NEW_STRING'/g" jboss-beans.xml
Run Code Online (Sandbox Code Playgroud)

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

$ echo  "s/'$OLD_STRING'/'$NEW_STRING'/g"
s/'<property name="webServiceHost">${jboss.bind.address}</property>'/'<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'/g
Run Code Online (Sandbox Code Playgroud)

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

sed -i "s#'$OLD_STRING'#'$NEW_STRING'#g" jboss-beans.xml
Run Code Online (Sandbox Code Playgroud)

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

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

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

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