
Tengo un registro que contiene líneas XML. Formato de muestra a continuación:
<head>
<body>
<line>
asdasd</line>
</body>
</head>
Quiero escanear el archivo de registro y agregar las líneas que no comienzan con '<' a la línea anterior. La salida sería como a continuación:
<head>
<body>
<line>asdasd</line>
</body>
</head>
Gracias
Respuesta1
Creo que ya he dicho esto antes, pero a riesgo de sonar como un disco atascado: NO uses expresiones regulares para analizar XML. Es frágil y propenso a romperse. Sin embargo, primero preguntaría: ¿por qué intentas hacer lo que estás haciendo? Porque debería ser irrelevante cuando trabaje con su XML.
En su lugar utilice un analizador:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->parsefile('your_file.xml');
foreach my $elt ( $twig->get_xpath('//#PCDATA') ) {
$elt->set_text( $elt->trimmed_text );
}
$twig->set_pretty_print('indented_a');
$twig->print;
Esto hace lo que desea... pero si realmente está trabajando con XML normalmente, ese trimmed_text
método probablemente elimina la necesidad de este procesamiento de todos modos.
Respuesta2
Perl al rescate!
perl -pe 'print "\n" if /^\s*+</; chomp;' input > output
es decir, la nueva línea se elimina de cada línea y se imprime cuando la siguiente línea comienza con un espacio en blanco seguido de un <
.
Para mantener la nueva línea final, cambie chomp
o chomp unless eof
agregueEND { print "\n" }
Respuesta3
Procedimiento sed casi estándar
sed '$!N;s/\n\(\s*[^<[:blank:]]\)/\1/;P;D' log.xml
Respuesta4
Usando la función XPath normalize-space
para eliminar la nueva línea inicial del /head/body/line
nodo:
xmlstarlet edit --update '/head/body/line' --expr 'normalize-space(text())' file.xml
O, usando nombres abreviados:
xmlstarlet ed -u '/head/body/line' -x 'normalize-space(text())' file.xml
El resultado, dada la entrada en la pregunta, sería
<?xml version="1.0"?>
<head>
<body>
<line>asdasd</line>
</body>
</head>
Úselo //line
en lugar de la ruta completa desde el nodo raíz si desea afectar a todos line
los nodos en su documento de entrada.
Añadir -O
o --omit-decl
después edit
o ed
descartar la <?xml ...>
declaración al inicio del documento resultante.