Remove todos os nós FOLDER! = tag value

3

Eu sei que os analisadores xml são a maneira ideal de ir até aqui, mas nenhum está disponível ou pode ser adicionado ao meu ambiente.

Vamos pegar o XML que segue a seguinte estrutura:

<CONTAINER>
  <FOLDER NAME="I_RS_INT">
  </FOLDER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
  <FOLDER NAME="I_RS_TRN">
  </FOLDER>
</CONTAINER>

Em um script bash, desejo remover todos os nós nos quais <FOLDER NAME= corresponde a *RS* OU remover todos os nós em que <FOLDER NAME != $var_folder

Qualquer ajuda muito apreciada!

    
por Chris Finlayson 27.10.2016 / 09:26

4 respostas

3

Isso deve ser feito:

cat /tmp/xml  | sed -e '/<FOLDER NAME=.*RS.*>/ { N; d; }'

Para cada linha que corresponde ao padrão entre os dois caracteres / , o código no {} é executado. N também leva a próxima linha ao espaço de padrão e, em seguida, apaga a coisa toda antes de passar para a próxima linha. Isso funciona em qualquer sed compatível com POSIX.

Tente abaixo para remover todas as linhas entre <FOLDER NAME=.*RS.*> e </FOLDER.> :

 awk '/<FOLDER NAME=.*RS.*>/,/<\/FOLDER>/ {next} {print}' xmlfile

O comando next interrompe o processamento da correspondência atual. Siga isso com um simples print .

    
por 27.10.2016 / 09:48
0

OK, a análise séria de XML com expressões regulares é bad notícias . XML NÃO é um idioma regular, portanto, nenhuma expressão regular pode manipulá-lo corretamente. Qualquer coisa que você escreva será hacky e quebradiça como resultado.

No entanto, XML tem algo semelhante a expressões regulares, chamado xpath .

Para resolver seu problema, eu faria assim:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
#process the file as XML
my $twig = XML::Twig -> parsefile ( 'your_file.xml' );

#iterate 'FOLDER' elements
foreach my $folder ( $twig -> get_xpath ('//FOLDER' ) ) {
   #delete any that regex match /RS/
   if ( $folder -> att('NAME') =~ m/RS/ ) { 
      $folder -> delete;
   }
}

#print the result. 
$twig -> set_pretty_print('indented_a');
$twig -> print;
    
por 18.11.2016 / 17:43
0
sed -r '/<FOLDER NAME=.*RS.*>/{ :X N; /<\/FOLDER>/d; bX }' file
<CONTAINER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
</CONTAINER>
    
por 21.01.2017 / 12:22
0

Você deve fazer isso com um analisador XML. Por exemplo, usando XMLStarlet na linha de comando:

$ xml ed -d '//FOLDER[contains(@NAME, "RS")]' data.xml
<?xml version="1.0"?>
<CONTAINER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
</CONTAINER>

Ou

$ var="I_R_INR"
$ xml ed -d "//FOLDER[@NAME != '$var']" data.xml
<?xml version="1.0"?>
<CONTAINER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
</CONTAINER>

Observe que esses dois não são equivalentes, pois o primeiro exemplo realiza uma correspondência de substring enquanto o segundo realiza uma correspondência exata.

    
por 21.01.2017 / 13:10