在 xml 文件中使用 sed 更改值
Posted
技术标签:
【中文标题】在 xml 文件中使用 sed 更改值【英文标题】:changing value using sed in xml file 【发布时间】:2021-03-29 20:31:13 【问题描述】:我想更改以下输入文件中的端口:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH</short>
<port protocol="tcp" port="22"/>
</service>
我尝试了以下命令但没有成功:
sed "s|\("^[[:space:]]*.+port[[:space:]]+protocol=.+port="\).*|\1\"3022\"\/>|" inputfile
但它没有改变。
当我 grep -E 它返回正确的行并突出显示正确的匹配:
# grep -E '^[[:space:]]*.+port[[:space:]]+protocol=.+port=' inputfile
<port protocol="tcp" port="22"/>
为什么 sed 不能完成这项工作?
更新:我找到了另一个命令来实现这一点:
sed -E '/short/,/service/ s/port=[^<]*/port=\"3022\"\/>/' inputfile
【问题讨论】:
您是否尝试过使用sed
使用-E
标志,就像使用grep
一样?
是的,然后返回错误“sed: -e expression #1, char 68: invalid reference \1 on `s' command's RHS”
Don't Parse XML/html With Regex. 我建议使用 XML/HTML 解析器 (xmlstarlet, xmllint ...)。
【参考方案1】:
为什么 sed 不能完成这项工作?
因为sed
regex 和grep
regex 是不同的,所以你必须转义哪些字符才能获得相同的含义。在sed
+
表示字面意思+
,我想你想要:
sed 's|\(^[[:space:]]*.\+port[[:space:]]\+protocol=.\+port=\).*|\1"3022"/>|'
而在扩展的 POSIX 正则表达式中 \(
表示文字 (
,而 (
开始一个组:
sed -E 's|(^[[:space:]]*.+port[[:space:]]+protocol=.+port=).*|\1"3022"/>|'
请注意,我还将引用从 "
更改为 '
以便于转义。
【讨论】:
以上是关于在 xml 文件中使用 sed 更改值的主要内容,如果未能解决你的问题,请参考以下文章