Deletar tudonós! = valor da tag

Deletar tudonós! = valor da tag

Eu sei que os analisadores XML são o caminho ideal para chegar 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 onde as <FOLDER NAME=correspondências *RS*OU remover todos os nós onde<FOLDER NAME != $var_folder

Qualquer ajuda muito apreciada!

Responder1

Isso deve servir :

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

Para cada linha que corresponda ao padrão entre os dois /caracteres, o código em {} é executado. N também leva a próxima linha para o espaço do padrão e d exclui tudo antes de passar para a próxima linha. Isso funciona em qualquer arquivo sed.

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

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

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

Responder2

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

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

Ou,

$ var="I_R_INR"
$ xmlstarlet ed -d "/CONTAINER/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 executa uma correspondência de substring enquanto o segundo executa uma correspondência exata.


Com o xqinvólucro ao redor jq:

$ xq -x --arg substring "RS" 'del(.CONTAINER.FOLDER[] | select(."@NAME" | contains($substring)))' file.xml
<CONTAINER>
  <FOLDER NAME="I_R_INR"></FOLDER>
</CONTAINER>
$ xq -x --arg name "I_R_INR" 'del(.CONTAINER.FOLDER[] | select(."@NAME" != $name))' file.xml
<CONTAINER>
  <FOLDER NAME="I_R_INR"></FOLDER>
</CONTAINER>

Responder3

OK, sério - analisar XML com expressões regulares émás notícias. XML NÃO é uma linguagem regular, portanto nenhuma expressão regular pode lidar com isso corretamente. Como resultado, qualquer coisa que você escrever será hackeada e frágil.

No entanto, XMLpossui algo semelhante às expressões regulares, chamadas xpath.

Para resolver o 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;

Responder4

sed -r '/<FOLDER NAME=.*RS.*>/{ :X N; /<\/FOLDER>/d; bX }' file
<CONTAINER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
</CONTAINER>

informação relacionada