'

'

XML 줄이 포함된 로그가 있습니다. 아래 샘플 형식:

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

로그 파일을 스캔하고 '<'로 시작하지 않는 줄을 이전 줄에 추가하고 싶습니다. 출력은 아래와 같습니다:

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

감사해요

답변1

전에도 말했듯이, 레코드가 멈춘 것처럼 들릴 위험이 있으므로 정규식을 사용하여 XML을 구문 분석하지 마세요. 부서지기 쉽고 부서지기 쉽습니다. 하지만 먼저 물어보고 싶습니다. 지금 하고 있는 일을 왜 하려고 하시나요? XML로 작업할 때는 관련이 없어야 하기 때문입니다.

대신 파서를 사용하십시오.

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

이것은 원하는 작업을 수행합니다. 그러나 실제로 XML을 정상적으로 사용하는 경우 이 trimmed_text방법을 사용하면 어쨌든 이 처리가 필요하지 않을 것입니다.

답변2

펄을 구출해주세요!

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

즉, 각 줄에서 개행 문자가 제거되고, 다음 줄이 공백으로 시작하고 뒤에 a가 올 때 인쇄됩니다 <.

마지막 개행 문자를 유지하려면 chomp다음으로 변경 chomp unless eof하거나 추가하세요.END { print "\n" }

답변3

거의 표준적인 sed 절차

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

답변4

XPath 함수를 사용하여 노드 normalize-space의 초기 개행을 제거합니다 /head/body/line.

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

또는 축약된 이름을 사용하여:

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

질문에 입력이 주어지면 출력은 다음과 같습니다.

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

입력 문서의 //line모든 노드에 영향을 미치려면 루트 노드의 전체 경로 대신 사용하십시오 .line

결과 문서의 시작 부분에 선언을 추가 하거나 -O삭제 --omit-decl합니다 edit.ed<?xml ...>

관련 정보