在bash在linux
问题描述:
替换XML值我有以下XML数据:在bash在linux
<info>
<data>
<name>my_image</name>
<value>site.com/image1.img</value>
</data>
<data>
<name>my_link</name>
<value>site.com/p_info</value>
</data>
</info>
我要全部更换site.com到siteimag.com每my_image值(只为my_image属性)的。
那么结果将是:
<info>
<data>
<name>my_image</name>
<value>siteimag.com/image1.img</value>
</data>
<data>
<name>my_link</name>
<value>site.com/p_info</value>
</data>
</info>
如何将其与sed命令来完成?
谢谢。
答
sed '/my_image/{n;s/site.com/siteimag.com/}' file
简要说明,
-
/my_image/
:搜索一行包含 “my_image” - 一旦字符串搜索,
- 通过使用命令
n
读取下一行。 -
s/site.com/siteimag.com/
:做替代
- 通过使用命令
答
同一个XML文档可以写,在许多不同的方式格式化, 因此用sed
简单的文字工具来更新它,将是非常脆弱的,容易打破。
例如只是添加name
和value
之间的空行,将打破天真sed
上面的脚本:
<data>
<name>my_image</name>
<value>site.com/image1.img</value>
</data>
它也不能真正遵循XML
结构,并会简单地更换任何site.com
参考,如果在一个my_image
模式它上面的线,即使是在一个注释:
<data>
<name>my_link</name> <!-- Used to be "my_image" -->
<value>site.com/p_info</value>
</data>
有数以百计的其他方式,源XML可以被修改,而不会改变它的意义,使之破坏或导致虚假的替代品。
为避免这种情况,您应该使用支持XML的工具来进行替换,例如, xmlstarlet
:
xmlstarlet ed \
-u "//data/name[text()='my_image']/../value" \
-x "concat(substring-before(.,'site.com'),'sitemag.com',substring-after(.,'site.com'))"|
data.xml
答
使用XML解析器的正确方法类似xmlstarlet:
xmlstarlet ed -u "//data/name[text()='my_image']/following-sibling::value" \
-v "$(sed 's/site/&imag/' <(xmlstarlet sel -t -v "//data/name[text()='my_image']/following-sibling::value" file.xml))" file.xml
输出:
<?xml version="1.0"?>
<info>
<data>
<name>my_image</name>
<value>siteimag.com/image1.img</value>
</data>
<data>
<name>my_link</name>
<value>site.com/p_info</value>
</data>
</info>
有sed的解析XML是坏主意 – RomanPerekhrest