Copiando conteúdo XML entre 2 tags de um arquivo para outro

0

Eu tenho dois arquivos XML.

1.xml

<abc>
....
....
</abc>

<xyz attrib1='1234'>
...
...
</xyz>

2.xml

<abc>
xxx
xxx
</abc>
<xyz attrib2='4321'>
xxx
xxxx
</xyz>

Eu preciso usar o shell script para substituir o conteúdo da tag 'xyz' no arquivo 1.xml pelo conteúdo em 2.xml para obter o arquivo final como:

<abc>
    ....
    ....
    </abc>
    <xyz attrib2='4321'>
    xxx
    xxxx
    </xyz>
    
por Abhishek Kothari 05.04.2017 / 07:59

4 respostas

1

com sed :

sed -n '/<xyz[ >]/,/<\/xyz>/p' 2.xml | \
sed '/<xyz[ >]/,/<\/xyz>/ { /<\/xyz>/! d; r /dev/stdin
    D; }' 1.xml >output.xml

Por favor, note que deve haver uma nova linha após /dev/stdin .

Outra maneira com sed , mais limpa, mas menos eficiente:

{
    sed '/<xyz[ >]/,$d' 1.xml
    sed -n '/<xyz[ >]/,/<\/xyz>/p' 2.xml
    sed '1,/<\/xyz>/d' 1.xml
} >output.xml
    
por 05.04.2017 / 08:32
1

Uma maneira correta (embora detalhada) de fazer isso seria usar um utilitário que reconhece XML, em vez de ferramentas genéricas de processamento de texto.

Por exemplo usando a transformação XSTL com xsltproc :

xsltproc - 1.xml <<EOF
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- Identity template (copy input to output) -->
    <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>   
    </xsl:copy>
    </xsl:template>

    <!-- Replace //xyz with its counterpart from 2.xml -->
    <xsl:template match="//xyz">
        <xsl:copy-of select="document('2.xml')//xyz"/>
    </xsl:template>
</xsl:stylesheet>
EOF

Isso substituirá corretamente //xyz em 1.xml pelo //xyz de 2.xml, independentemente da codificação de texto, formatação, uso de referências de entidades e.t.c.

    
por 05.04.2017 / 18:37
0
sed "
    /<xyz/,/<\/xyz>/c\
        $(
            sed -n '
                /<xyz/{
                    :a;
                    N;
                    /<\/xyz>/! ba;
                    s/\n/\&/gp;
                    }
                ' 2.xml
        )
    " 1.xml

Quanto a mim, é muito fácil colocar linhas necessárias de 2.xml e substituir ( c ) linha (s) apropriada (s) em 1.xml Observação: o comando c não pôde aceitar entrada de várias linhas, portanto, precisamos adicionar \ entre as linhas.

    
por 05.04.2017 / 10:42
0
perl -0777ne '                                # slurp xmls
   $tag2 or ($tag2) = /(<xyz.*<\/xyz>)/s;     # grab tag <xyz> from 2.xml
   @ARGV or print s|<xyz.+?</xyz>|$tag2|srg;  # replace tag <xyz> in 1.xml globally
' 2.xml 1.xml
    
por 05.04.2017 / 16:02