替换XML文件中的动态内容

时间:2012-11-13 22:24:47

标签: xml bash dynamic text replace

快速摘要:我需要创建一个Bash脚本,以便每周自动更改节点内的文本。脚本将匹配节点并替换它们内部的文本(如果可能的话)?我该怎么做?

长摘要: 我托管了一个Minecraft服务器,它有商店,每个商店在/ ShowcaseStandalone / ffs-storage /目录中都有自己的.xml文件。每个星期天我的服务器重新启动并执行几个命令到终端重置几件事。我试图改变的一件事是商店之一。我想要更改节点中的文本< itemstack>以及节点< price>中的文本。我只是想从不同文件夹中的.txt文件中获取文本,并将其插入该节点。问题是,节点中的文本每周都会更改。有没有办法用bash替换两个节点中的特定行或文本?

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<scs-shop usid="cac8480951254352116d5255e795006252d404d9" version="2" type="storage">
    <enchantments type="string"/>
    <owner type="string">Chadward27</owner>
    <world type="string">Frisnuk</world>
    <itemStack type="string">329:0</itemStack>
    <activity type="string">BUY</activity>
    <price type="double">55.0</price>
    <locX type="double">487.5</locX>
    <locY type="double">179.0</locY>
    <locZ type="double">-1084.5</locZ>
    <amount type="integer">0</amount>
    <maxAmount type="integer">0</maxAmount>
    <isUnlimited type="boolean">true</isUnlimited>
    <nbt-storage usid="23dffac5fb2ea7cfdcf0740159e881026fde4fa4" version="2" type="storage"/>
</scs-shop>

操作系统:Linux Ubuntu 12.04

3 个答案:

答案 0 :(得分:17)

您可以使用xmlstarlet编辑XML中的shell文件,如下所示:

xmlstarlet edit -L -u "/scs-shop/price[@type='double']" -v '99.66' file.xml

注意

  • "/scs-shop/price[@type='double']"是一个Xpath表达式
  • 请参阅xmlstarlet ed --help

答案 1 :(得分:12)

XML方式很酷,但是如果你需要使用普通的bash工具,你可以使用sed修改一行。例如:

PRICE=123
sed -i "s/\(<price.*>\)[^<>]*\(<\/price.*\)/\1$PRICE\2/" $XML_FILE_TO_MODIFY

这将用123代替价格。

那个sed命令似乎令人生畏,所以让我分解一下:

\(<price.*>\)[^<>]*\(<\/price.*\)是要匹配的模式。 \( ... \)是分组的括号。 <price.*>与开盘价标签相匹配。 [^<>]*匹配除尖括号之外的任何内容,在这种情况下,它将匹配价格标签的内容。 <\/price.*与价格标签的末尾匹配。正斜杠是sed中的分隔符,所以我用反斜杠转义它。

\1$PRICE\2是用于替换匹配文本的文本。 \1是指第一个匹配的括号组,即开盘价标签。 $PRICE是具有所需价格的变量。 \2引用第二个括号组,在本例中为结束标记。

答案 2 :(得分:2)

我没有拥有xmlstarlet的奢侈品。 我只是通过内联替换找到了解决方案;

<强>模板parameter.xml

<ns:Parameter>
    <ns:Name required="true">##-ParamName-##</ns:Name>
    <ns:Value>
        <ns:Text>##-ParamValue-##</ns:Text>
    </ns:Value>
</ns:Parameter>

<强>段

tokenName="foo"
tokenValue="bar"    

#Replace placeholders in parameter template element
myParamElement=$(cat template-parameter.xml)
myParamElement=${myParamElement//##-ParamName-##/$tokenName}
myParamElement=${myParamElement//##-ParamValue-##/$tokenValue}  

<强>结果

<ns:Parameter>
    <ns:Name required="true">foo</ns:Name>
    <ns:Value>
        <ns:Text>bar</ns:Text>
    </ns:Value>
</ns:Parameter>