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이 구출하러 옵니다!
perl -pe 'print "\n" if /^\s*+</; chomp;' input > output
즉, 각 줄에서 개행 문자를 제거하고 <
다음 줄이 공백으로 시작하고 뒤에 가 오면 인쇄합니다.
마지막 줄 바꿈을 유지하려면 다음 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 ...>