Como anexar uma linha que não começa com '

Como anexar uma linha que não começa com '

Eu tenho um log que contém linhas XML. Exemplo de formato abaixo:

<head>
    <body>
        <line>
asdasd</line>
    </body>
</head>

Quero verificar o arquivo de log e anexar as linhas que não começam com '<' à linha anterior. A saída seria como abaixo:

<head>
    <body>
        <line>asdasd</line>
    </body>
</head>

Obrigado

Responder1

Acho que já disse isso antes - mas correndo o risco de soar como um disco travado - NÃO use expressões regulares para analisar XML. É frágil e propenso a quebrar. Eu perguntaria primeiro: por que você está tentando fazer o que está fazendo? Porque deveria ser irrelevante ao trabalhar com seu XML.

Em vez disso, use um analisador:

#!/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;

Isso faz o que você deseja... mas se você estiver trabalhando normalmente com o XML, esse trimmed_textmétodo provavelmente elimina a necessidade desse processamento de qualquer maneira.

Responder2

Perl para o resgate!

perl -pe 'print "\n" if /^\s*+</; chomp;' input > output

ou seja, a nova linha é removida de cada linha e é impressa quando a próxima linha começa com um espaço em branco seguido por um <.

Para manter a nova linha final, altere chompou chomp unless eofadicioneEND { print "\n" }

Responder3

Procedimento sed quase padrão

sed '$!N;s/\n\(\s*[^<[:blank:]]\)/\1/;P;D' log.xml

Responder4

Usando a função XPath normalize-spacepara remover a nova linha inicial do /head/body/linenó:

xmlstarlet edit --update '/head/body/line' --expr 'normalize-space(text())' file.xml

Ou, usando nomes abreviados:

xmlstarlet ed -u '/head/body/line' -x 'normalize-space(text())' file.xml

A saída, dada a entrada na questão, seria

<?xml version="1.0"?>
<head>
  <body>
    <line>asdasd</line>
  </body>
</head>

Use //lineno lugar do caminho completo do nó raiz se desejar afetar todos os linenós no seu documento de entrada.

Adicione -Oou --omit-declapós editou edpara descartar a <?xml ...>declaração no início do documento resultante.

informação relacionada