Замена значения в xml с использованием переменной sed - PullRequest
0 голосов
/ 14 октября 2019

Я хочу заменить значение, которое я нашел, используя 'grep' в XML-файле. Значение передается в переменной, и я для этого использую «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 голосов
/ 15 октября 2019

решение 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>
0 голосов
/ 14 октября 2019

Отказ от ответственности: Как уже упоминалось в комментариях, это опасный хак . Это может привести к непреднамеренным побочным эффектам, если вы не уверены из ограничений на ввод. Если замена 9090 на строке, содержащей Port в пределах 8 строк строки, содержащей 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>
...