![sed 명령을 사용하여 XML 요소 사이의 단어 읽기](https://linux55.com/image/176613/sed%20%EB%AA%85%EB%A0%B9%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20XML%20%EC%9A%94%EC%86%8C%20%EC%82%AC%EC%9D%B4%EC%9D%98%20%EB%8B%A8%EC%96%B4%20%EC%9D%BD%EA%B8%B0.png)
command 을 사용하여 두 xml 요소 사이의 단어를 읽고 싶습니다 sed
.
예를 들어 다음 xml에서 숫자 1234567을 읽고 싶습니다.
<ns1:account>
<ns2:name>Corporation</ns2:name>
<address>
<StrtNm>NewYork</StrtNm>
<BldgNb>3</BldgNb>
<PstCd>230300</PstCd>
<Ctry>USA</Ctry>
</address>
</ns1:account>
<ns3:details>
<ns4:accnum>
<ns5:info>
<nd6:accnum>1234567</nd6:accnum>
</ns5:info>
</ns4:accnum>
</ns3:details>
grep
아래와 같이 및 명령을 sed
조합하여 이 작업을 수행 할 수 있습니다 .
grep -oz '<.*details>\s*<.*accnum>\s*<.*info>\s*<.*accnum>[0-9]*</.*accnum>' test.xml |sed -n 's:.*<.*accnum>\(.*\)</.*accnum>.*:\1:p'
grep -oz
하지만 이는 전체 파일을 한 줄로 취급하기 때문에 성능에 좋지 않다는 것을 읽었습니다 . 그래서 두 명령을 모두 사용해 보았지만 sed
파일 형식이 올바른 경우에만 작동합니다(위에 표시된 대로). XML이 한 줄이고 인쇄가 제대로 되지 않으면 작동하지 않습니다. 내가 시도한 것은 다음과 같습니다.
sed -n '/.*details>/,/<\/.*accnum>/p' test.xml |sed -n 's:.*<.*accnum>\(.*\)<.*accnum>:\1:p'
도전:
- 파일의 요소에는 네임스페이스 접두사가 있을 수도 있고 없을 수도 있습니다.
- 파일 크기가 약 100Mb 이상으로 상당히 큽니다.
- 파일 내용은 올바른 형식의 xml이거나 전체 xml이 한 줄일 수 있습니다.
위에 나열된 명령을 사용하는 기존 스크립트가 애플리케이션에 있으므로 아직 명령을 시도하지 않았 awk
으며 동일한 작업을 수행할 수 있기를 바랍니다.
답변1
XML을 올바른 형식의 문서로 만들기 위해 편집해야 했습니다(요소 추가 <root/>
및 네임스페이스 선언).
<?xml version="1.0"?>
<root xmlns:ns1="urn:ns1" xmlns:ns2="urn:ns2" xmlns:ns3="urn:ns3" xmlns:ns4="urn:ns4" xmlns:ns5="urn:ns5" xmlns:nd6="urn:nd6">
<ns1:account>
<ns2:name>Corporation</ns2:name>
<address>
<StrtNm>NewYork</StrtNm>
<BldgNb>3</BldgNb>
<PstCd>230300</PstCd>
<Ctry>USA</Ctry>
</address>
</ns1:account>
<ns3:details>
<ns4:accnum>
<ns5:info>
<nd6:accnum>1234567</nd6:accnum>
</ns5:info>
</ns4:accnum>
</ns3:details>
</root>
xmlstarlet
이 작업이 완료되면 XML 파일을 구문 분석하고 필요한 요소를 정확하게 추출하는 데 사용할 수 있습니다.
xmlstarlet sel -t -v '//nd6:accnum' -n x.xml
1234567
필요한 경우 XPath를 수정하여 더 정확하게 만들 수 있습니다. 예를 들어, /root/ns3:details/ns4:accnum/ns5:info/nd6:accnum
이것은 극단적인 선택이 될 것입니다.
해당 기능이 없다면 xmlstarlet
설치하는 것을 적극 권장합니다. 시스템이 귀하가 관리하는 시스템이 아닌 경우 작업 중인 모든 프로젝트의 전제 조건으로 만드십시오. sed
XML 파일을 사용하고 구문 분석하는 것은 awk
단기적으로는 효과가 있을 수 있지만 나중에 기술적 부채가 발생하게 됩니다. 특히 XML 문서의 정확한 레이아웃(공백, 줄 바꿈, 주석 등)을 제어할 수 없는 경우 더욱 그렇습니다.
답변2
xidel 및 유효한 xml 입력(@roaima 답변 참조)을 사용하여 다음을 수행할 수 있습니다.
xidel -se '//nd6:accnum/text()' file.xml
어디
//nd6:accnum/text()
어디에서나 "nd6:accnum" 요소를 찾아 해당 텍스트를 선택하는 데 사용되는 XPath 표현식입니다.
답변3
이 한 줄짜리 Perl 명령은 예상된 결과를 인쇄합니다.
perl -lne 'print "$1" if /<nd6:accnum>(\w+)</' file.xml
1234567