다음과 같은 XML 파일이 있습니다.
<FileHeader>SampleFile</FileHeader>
<Name>aaaa</Name>
<Place>bufnkf</Place>
<Name> bjfbhj</Name>
<Place>bvdhbf</Place>
<FileFooter><Record>2</Record></FileFooter>
레코드 태그의 값을 추출하고 싶습니다. 아래와 같이 sed 명령을 사용하지만 출력이 제공되지 않습니다.
sed -n '/Record/{s/.*<Record>//;s/<\/Record.*//;p;}' filename
이에 대한 도움이 필요하신가요?
답변1
FileFooter/Record
노드의 값을 스크립트의 셸 변수에 넣는 가장 쉬운 방법은 xmlstarlet
.
다음은 XML 문서가 잘 구성되어 있다고 가정하지만 예제 문서에는 루트 태그가 여러 개 있기 때문이 아닙니다(가장 흥미롭다고 생각하는 비트를 추출했기 때문이라고 가정합니다). 또한 노드가 하나만 있다고 가정합니다 FileFooter/Record
. 그렇지 않으면 값을 반복해야 합니다.
value=$( xmlstarlet sel -t -v '//FileFooter/Record' file.xml )
표현식은 //FileFooter/Record
우리가 관심 있는 노드의 XPath입니다(실제로는각 FileFooter/Record
문서 전체의 노드). 를 통해 sel -t -v
특정 또는 XPath() 를 일치시켜 얻은 값을 추출하고 싶다고 알려줍니다 xmlstarlet
.-v
sel -t
문제의 데이터에 루트 태그가 누락되어 있으므로 다음 명령을 실행하여 누락된 태그를 동적으로 삽입하고, 수정된 문서를 구문 분석하고, 쉘 변수에서 필요한 값을 추출할 수 있습니다 value
.
value=$(
{ echo '<root>'; cat file.xml; echo '</root>'; } |
xmlstarlet sel -t -v '//FileFooter/Record'
)
누락된 단일 루트 노드가 호출된다고 가정하면 다음을 root
사용할 수도 있습니다 .xq
https://kislyuk.github.io/yq/), JSON 파서 주위에 구축된 XML 파서 레이어입니다 jq
.
value=$( xq -r '.root.FileFooter.Record' file.xml )
.[].FileFooter.Record
루트 노드의 이름을 입력하고 싶지 않은 경우 이 방법을 사용할 수 있습니다( FileFooter
그러나 여전히 루트 노드 바로 아래에 있는 노드라고 가정합니다).
이 명령은 XML 파일을 JSON으로 변환합니다. XML 문서가 다음과 같은 경우:
<?xml version="1.0"?>
<root>
<FileHeader>SampleFile</FileHeader>
<Name>aaaa</Name>
<Place>bufnkf</Place>
<Name> bjfbhj</Name>
<Place>bvdhbf</Place>
<FileFooter>
<Record>2</Record>
</FileFooter>
</root>
유틸리티 xq
는 이를 다음 JSON 문서로 변환합니다.
{
"root": {
"FileHeader": "SampleFile",
"Name": [
"aaaa",
"bjfbhj"
],
"Place": [
"bufnkf",
"bvdhbf"
],
"FileFooter": {
"Record": "2"
}
}
}
xq
그런 다음 jq
표현식을 사용하여 호출하여 .root.FileFooter.Record
값을 추출합니다.