
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 ...>