다음과 같은 XML 파일이 있습니다.
<id>456</id>
<root>
<value>1</value>
<intNum>2</intNum>
</root>
<root>
<eulav>1</eulav>
<muNtni>2</muNtni>
</root>
<id>456</id>
나는 기억 하고 다음을 수행하고 싶습니다 .
sed 's/\<root\>/\
\<root\>
$herecomestheid
기본적으로 이것이 하는 일은 <root>
로 바꾸는 것입니다 <root>\n<id>456</id>
. \n
이 경우 개행을 의미합니다. 나는 이것을 이미 알고 있지만, 내가 겪고 있는 문제는 그것을 기억 <id>456</id>
하고 나중에 사용하기 위해 보관하는 것입니다.
나는 이것을 시도했습니다 (분명히 작동하지 않습니다).
sed -i '' 's/\<root\>/\
\<root\>\
\<id\>.\<\/id\>/g'
나는 다음과 같이하려고합니다 :
cat file.xml | grep '\<id\>*\<\/id\>'
grep 출력을 변수에 넣어보십시오. 이것도 분명히 작동하지 않습니다.
편집: <id>*</id>
루트 디렉터리에 있어야 합니다.
답변1
XML을 텍스트로 처리하는 것은 일반적으로 신뢰할 수 있는 솔루션이 아니지만 그렇게 해야 한다고 주장한다면 sed를 사용할 수 있습니다.예비 공간 예를 들어
sed -e '/<id>[0-9]*<\/id>/h' -e '/<root>/{x;p;x;}' file.xml
답변2
sed -e :b -e '$!{N;\|<id>.*\n<root>|!bb
};do what ever you want to do with all of those lines now....'
나는 oldspace가 아마도 최선의 선택일 것이라는 Steeldriver의 의견에 동의 h
하지만 다른 옵션도 있습니다. 때때로 우리는 두 개의 버퍼를 관리하기에는 너무 게으른 경우가 있습니다. 또는 이것이 일반적으로 내 문제입니다.예두 개의 버퍼를 관리합니다. 위의 코드 조각은 패턴 공간에 줄을 쌓습니다. 을 텐데항상 태그 사이에 나타나며 <id>
, 라인 2로 이동하기 전에 항상 필요한 데이터 청크로 패턴 공간을 재귀적으로 채웁니다.즉, 버퍼가 동시에 붕괴되지 않는 한 그렇게 할 것입니다. 하지만 이제는 그렇게 하기가 다소 어렵습니다..
h
또한, 예전의 우주 문제 로 돌아가서 , 전자적 x
변화는교환 h
오래되고 패턴화된 공간. 한 번 사용하면 모드 버퍼가 h
이전 버퍼로 렌더링되고 그 반대의 경우도 마찬가지입니다. 이 효과는 라인 사이클 동안 지속됩니다. 내가 일반적으로 하는 일은 시작선에 도달할 때까지 파일을 읽고, 예비 편집을 수행한 다음, H
다른 상태를 얻을 때까지 이전 상태를 교환하고 유지하는 것입니다. 내 스크립트가 다시 바뀌면 한 블록 뒤쳐집니다. 마지막으로 열었던 태그 H
와 동시에 모든 필드가 뒤쳐집니다. 필요할 때 필요한 만큼만 버퍼링하는 간단한 방법입니다.
원하는 루프를 달성하는 또 다른 방법은 다음과 같습니다.
sed -e '/<id>/h;//!H;/<root>/!{$!d' -e '};x...'
그 시점부터 패턴 공간은 H
이전 공간이 되고 그 반대도 마찬가지입니다. h
옛 의지씌우다 h
이전 공간이 사용될 때마다 현재 모드 공간과 함께 사용됩니다. 따라서 위의 예에서는 <id>
매번 한 줄로 새 버퍼를 시작합니다.!H
추가H
이전 공간의 모든 중간 줄 뒤에는 \n
줄 문자가 옵니다. 현재 라인이 안전하게 들어가고 다음 라인 루프가 시작되면 $!d
마지막 라인이 아닌 모든 라인의 패턴 공간이 제거되므로 일치를 기다리는 전체 블록에서만 변경이 발생합니다.!
$
H
x
<root>
당신의 그것을 기억하십시오마침내<root>
차단하면 일치 항목과 다를 경우 태그가 마지막 줄이 될 수 있습니다 .
하지만...
편집 내용에 따르면 탈출할 수 없는 이유가 없다고 생각됩니다.
sed '/<id>/h;//d;\|</root>|G
' <<\INPUT
unimportant 1
<id> number 1 </id>
<root> sub text
more text
more text
</root>
<root> sub text as well
and more text
and more text
</root>
unimportant 2
<id> number 2 </id>
<root> sub text
more text
more text
</root>
<root> sub text
and more text
and more text
</root>
INPUT
필드 <id>
인 줄이 있습니다 .h
(다시 말하지만 h
이전 공간 덮어쓰기)그런 다음 d
출력에서 제거하십시오. 일치가 발생 하면 다음과 같이 </root>
라인 사이클의 끝에서 결과를 자동으로 인쇄하기 전에 이전 공간이 패턴 공간에 추가됩니다 .sed
G
h
unimportant 1
<root> sub text
more text
more text
</root>
<id> number 1 </id>
<root> sub text as well
and more text
and more text
</root>
<id> number 1 </id>
unimportant 2
<root> sub text
more text
more text
</root>
<id> number 2 </id>
<root> sub text
and more text
and more text
</root>
<id> number 2 </id>
답변3
사용된 솔루션 awk
은
awk '/<id>/{id=$0}/<root>/{print id}1' file.xml
해당 줄을 인쇄하지 않으려면 를 <id>
추가하여 건너뛸 수 있습니다 next
.
awk '/<id>/{id=$0;next}/<root>/{print id}1' file.xml