使用带有sed的变量替换xml中的值

时间:2019-10-14 16:35:21

标签: bash sed

我想替换一个在xml文件中使用“ grep”找到的值。值是通过变量传递的,为此我使用了“ sed”。

$ echo $AdmServerPort
9595
$ grep -A 8 AdmServer PoolServer.xml | grep Port
        <Argument Name="Port" Value="9090"/>
$ grep -A 8 AdmServer PoolServer.xml | grep Port | xargs sed "s/9090/$AdmServerPort/g"
sed: can't read <Argument: No such file or directory
sed: can't read Name=Port: No such file or directory
: No such file or directory>

请帮助我找到我在这里做错了什么?预先感谢。

2 个答案:

答案 0 :(得分:0)

免责声明:正如人们在评论中提到的那样,这是一个危险的骇客。除非您对输入的约束肯定,否则它可能会产生意想不到的副作用。如果您正要在包含9090的行的8行中替换包含Port的行中的AdmServer,那么可以这样做:

sed "/AdmServer/,+8 {/Port/s/9090/$AdmServerPort/}" PoolServer.xml

如果要修改文件,请使用-i标志。

示例输入:

<AdmServer>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
</AdmServer>

示例输出:

<AdmServer>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9595"/>
    <Argument Name="Port" Value="9595"/>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9595"/>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9595"/>
    <Argument Name="Port" Value="9595"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Foo" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
</AdmServer>

答案 1 :(得分:0)

libxml解决方案: 您可以将新的Port属性值作为参数传递给xsltproc,以在身份转换样式表中使用:

xsltproc --stringparam new_port 9595 PoolServer.xsl PoolServer.xml

PoolServer.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- define $new_port as a parameter received from the shell -->
    <xsl:param name="new_port"/>

    <!-- match AdmServer/Argument 'Value' attributes
         whose sibling 'Name' attributes are 'Port' -->
    <xsl:template match="AdmServer/Argument/@Value[../@Name = 'Port']">
        <xsl:attribute name="Value">
            <xsl:value-of select="$new_port"/>
        </xsl:attribute>
    </xsl:template>

    <!-- recursively copy the rest of the xml document -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输入PoolServer.xml:

<AdmServer>
    <Argument Name="Sample1" Value="1234"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Sample2" Value="1234"/>
    <Argument Name="Port" Value="9090"/>
    <Argument Name="Port" Value="9090"/>
</AdmServer>

输出:

<?xml version="1.0"?>
<AdmServer>
    <Argument Name="Sample1" Value="1234"/>
    <Argument Name="Port" Value="9595"/>
    <Argument Name="Sample2" Value="1234"/>
    <Argument Name="Port" Value="9595"/>
    <Argument Name="Port" Value="9595"/>
</AdmServer>