如何在BASH脚本中向类似XML的文件中的标记添加值?

时间:2014-07-14 22:16:26

标签: xml bash shell awk sed

我有一个名为metadata.xml的文件,其中包含(唯一)标记MissingVal,以及其他许多文件:

metadata.xml:

<foo1>
    someData
</foo1>
<foo2>
    123.54
</foo2>
<MissingValue>

</MissingValue>
<foo3>
    1.0
</foo3>

我正在使用BASH脚本来处理此文件。在脚本中,我将变量SomeVal设置为数字&#34; real&#34;价值:SomeVal=1234567890.0

如何让我的BASH脚本将SomeVal的值写入<MissingValue>文件中的metadata.xml标记?运行脚本应使metadata.xml如下所示:

metadata.xml:

<foo1>
    someData
</foo1>
<foo2>
    123.54
</foo2>
<MissingValue>
    1234567890.0
</MissingValue>
<foo3>
    1.0
</foo3>

我想我可以使用awksed来做这件事,但我对这些程序不够熟悉,无法取得很大进展。

提前致谢!

3 个答案:

答案 0 :(得分:0)

sh$ export SomeVal=1234567890.0
sh$ perl \
     -0pe \
     "s|<MissingValue>\s*</MissingValue>|<MissingValue>$SomeVal</MissingValue>|sg" \
     metadata.xml

产:

<foo1>
    someData
</foo1>
<foo2>
    123.54
</foo2>
<MissingValue>1234567890.0</MissingValue>
<foo3>
    1.0
</foo3>

答案 1 :(得分:0)

不要使用shell,不要使用awk,不要使用sed,不要使用任何其他文本处理工具。使用xsltproc或其他一些用于处理xml的类似工具。

使用具有单个根节点的正确构造的xml文档,以下转换将在xsltproc --stringparam SomeValue "$SomeVal" metadata.xsl metadata.xml

运行时执行您想要的操作
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="SomeValue"/>

    <!-- Whenever you match any node or any attribute -->
    <xsl:template match="@*|node()">
        <!-- Copy the current node -->
        <xsl:copy>
            <!-- Including any attributes it has and any child nodes -->
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="MissingValue">
        <xsl:copy>
            <!-- Including any attributes it has and any child nodes -->
            <xsl:apply-templates select="@*"/>
            <xsl:text>
    </xsl:text>
            <xsl:value-of select="normalize-space($SomeValue)"/>
            <xsl:text>
</xsl:text>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

我绝不是一位xslt专家,因此可能有更好的方法来做到这一点。

答案 2 :(得分:0)

以下是awk

的使用方法
SomeVal=1234567890.0
awk '/<MissingValue>/ {$0=$0"\n    "v}1' v="$SomeVal" metadata.xml
<foo1>
    someData
</foo1>
<foo2>
    123.54
</foo2>
<MissingValue>
    1234567890.0

</MissingValue>
<foo3>
    1.0
</foo3>