2017-10-16 160 views
-1

替换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命令来完成?

谢谢。

+0

有sed的解析XML是坏主意 – RomanPerekhrest

回答

1
sed '/my_image/{n;s/site.com/siteimag.com/}' file 

简要说明,

  • /my_image/:搜索一行包含 “my_image”
  • 一旦字符串搜索,
    • 通过使用命令n读取下一行。
    • s/site.com/siteimag.com/:做替代
1

同一个XML文档可以写,在许多不同的方式格式化, 因此用sed简单的文字工具来更新它,将是非常脆弱的,容易打破。

例如只是添加namevalue之间的空行,将打破天真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 
0

使用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>