Como remover uma linha de uma tag no shell script?

1

Temos um arquivo xml (abc_lop.xml) no qual preciso remover uma linha que está presente em uma tag:

Abaixo está um arquivo xml, eu o encurtei porque é muito grande.

<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">


    <!-- some data here  -->

</HELLO>

Como você pode ver, eu tenho essa linha xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd" na tag HELLO acima. Eu preciso remover essa linha e manter outras coisas.

A partir de agora, estou adicionando alguns cabeçalhos e rodapés ao arquivo xml acima, mostrado abaixo no meu shell script e, em seguida, armazenando-o na variável de arquivo: Here $word is abc .

file=$(printf '%s\n%s\n%s' "$header" "$(cat "$path/${word}_lop.xml")" "$footer")

Agora, quero ter certeza de que a variável de arquivo deve ter os dados do arquivo xml, mas com essa linha, remova também da tag HELLO .

Estou usando essa variável $file mais tarde para outra finalidade, portanto, quero garantir que $file tenha o cabeçalho, o rodapé e a linha removidos também. Essa linha que tem par chave = valor só estará presente uma vez.

    
por user1950349 17.09.2015 / 07:17

2 respostas

1

Para remover a entrada xsi:schemaLocation , deixe o restante do arquivo intacto:

$ sed 's/xsi:schemaLocation="[^"]*"//' "$path/${word}_lop.xml"
<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >


    <!-- some data here  -->

</HELLO>

s/xsi:schemaLocation="[^"]*"// é um comando substituto. Ele substitui qualquer coisa que corresponda ao regex xsi:schemaLocation="[^"]*" com nada.

Para combinar isso com seu script:

file=$(printf '%s\n%s\n%s' "$header" "$(sed 's/xsi:schemaLocation="[^"]*"//' "$path/${word}_lop.xml")" "$footer")
    
por 17.09.2015 / 07:26
2

POR FAVOR, não use expressões regulares para mexer com XML. A especificação XML permite um monte de coisas que simplesmente não combinam bem com a análise baseada em regex.

É uma idéia muito ruim porque você cria um código frágil. Um dia, o XML de origem que você está usando pode simplesmente mudar para outra coisa perfeitamente válida (no que diz respeito à especificação XML) e seu script de fluxo secundário de munging será interrompido.

Este é exatamente o tipo de coisa que deixa os administradores de sistemas e programadores de manutenção muito tristes.

POR FAVOR, use um analisador XML. xmlstarlet é uma opção. O perl e o python também possuem opções de análise. Ambas as coisas lidam com casos estranhos em XML (como quebra automática de linha, impressão bonita, etc.) e asseguram que seu XML downstream é válido - é importante gerar um XML válido, porque o supostamente é inválido condição fatal.

Então, especificamente - removendo um atributo do seu elemento HELLO :

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> new ( 'pretty_print' => 'indented_a' ) -> parse ( \*DATA );

foreach my $hello ( $twig -> findnodes ('//HELLO') ) {
    $hello -> del_att('xmlns:xsi');
}
$twig -> print;

__DATA__
<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">


    <!-- some data here  -->

</HELLO>

Nota - Eu 'imprimi bem' o resultado:

<HELLO
    version="4.2"
    xmlns="http://www.bacd.org/HELLO-4_2"
    xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">
    <!-- some data here  -->
</HELLO>

Para nos dar um exemplo de porque a análise baseada em regex é uma má ideia - porque é XML válido.

Então é:

<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">
    <!-- some data here  -->
</HELLO>

E:

<HELLO
version="4.2"
xmlns="http://www.bacd.org/HELLO-4_2"
xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd"
>
    <!-- some data here  -->
</HELLO>

E:

<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd"><!-- some data here  --></HELLO>

Mas os analisadores XML são fáceis e bons de usar.

Para simplificar seu código em um único liner como o sed:

perl -0777 -MXML::Twig -e 'XML::Twig -> new ( pretty_print => "indented_a", twig_handlers => { "HELLO" => sub { $_ -> del_att("xmlns:xsi") }} ) -> parse ( <> ) -> print;'

Deve funcionar se dados alimentados no STDIN ou através da especificação de um nome de arquivo.

    
por 21.09.2015 / 17:13