태그 값을 추출하는 쉘 스크립트

태그 값을 추출하는 쉘 스크립트

아래에 언급된 XML 파일이 하나 있고 unix 명령을 사용하여 애플리케이션 이름, 시스템 및 상태 태그 값을 추출하고 이를 쉼표로 구분된 형식으로 표시하려고 한다고 가정합니다.

XML 파일:-

 <?xml version="1.0" encoding="UTF-8"?>
<applications>
<application name="Adapter/Code1">
<service name="Code1.par">
<deploymentStatus>Success</deploymentStatus>
<serviceInstance name="Code1-One">
    <machine>123</machine>
    <status>Running</status>
</serviceInstance>
<serviceInstance name="Code1-Two">
    <machine>456</machine>
    <status>Running</status>
</serviceInstance>
</service>
</application>
<application name="Adapter/Code2">
<service name="Code2.par">
<deploymentStatus>Success</deploymentStatus>
<serviceInstance name="Code2-One">
    <machine>123</machine>
    <status>Running</status>
</serviceInstance>
<serviceInstance name="Code2-Two">
    <machine>456</machine>
    <status>Running</status>
</serviceInstance>
</service>
</application>
</applications>

산출:-

Adapter/Code1,123,Running

Adapter/Code1,456,Running

Adapter/Code2,123,Running

Adapter/Code2,456,Running

이 활동을 수행하기 위한 unixcommand/shell 스크립트를 제공하는 데 도움을 주실 수 있습니까?

미리 감사드립니다!!!

답변1

파이썬3.x 솔루션(xml.etree.ElementTree기준 치수):

import xml.etree.ElementTree as ET

tree = ET.parse("test.xml")
root = tree.getroot()
for app in root.findall('application'):
    for m,s in zip(app.iter('machine'), app.iter('status')):
        print("%s,%s,%s" % (app.get('name'), m.text, s.text))

출력:

Adapter/Code1,123,Running
Adapter/Code1,456,Running
Adapter/Code2,123,Running
Adapter/Code2,456,Running

https://docs.python.org/3.6/library/xml.etree.elementtree.html?highlight=etree#module-xml.etree.ElementTree


xmlstarlet+(각 요소의 하위 노드를 그룹화하는 데 사용됨 application) 솔루션:

xmlstarlet sel -t -v "//application/@name| .//machine/text()| .//status/text()" -n input.xml 
 | awk '/Adapter/{app=$0; r=app; c=0; next}
   { if(++c==2){ c=0; print r","$0; r=app } else { r=r","$0 }}'

출력:

Adapter/Code1,123,Running
Adapter/Code1,456,Running
Adapter/Code2,123,Running
Adapter/Code2,456,Running

  • "//application/@name| .//machine/text()| .//status/text()"- 필요한 노드를 얻기 위한 XPath 표현식

  • /Adapter/{app=$0; r=app; c=0; next}- application추가 연결을 위해 각 이름을 캡처합니다.

http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.html

답변2

설치하다자델그리고 xpath를 사용하세요.

내 생각에 가장 좋은 관점은 다음과 같습니다 serviceInstance.

xidel f.xml -e '//serviceInstance/string-join((../../@name, machine, status),",")'
Adapter/Code1,123,Running
Adapter/Code1,456,Running
Adapter/Code2,123,Running
Adapter/Code2,456,Running

답변3

xmlstarlet각 노드를 반복하는 데 사용 serviceInstance:

xmlstarlet sel -t \
    -m '//application/service/serviceInstance' \
    -v '../../@name' -o , \
    -v 'machine' -o , \
    -v 'status' -nl \
    file.xml

이는 serviceInstance노드와 일치하며, 각 노드에 대해 name상위 노드의 속성, machine노드 값 및 status노드 값을 추출합니다. 사이에 쉼표( -o ,)가 있고 끝에 줄 바꿈( -nl)이 포함되어 출력됩니다.

xq다음 에서 인용된 CSV 출력을 얻을 수도 있습니다 .https://kislyuk.github.io/yq/):

xq -r '
    .applications.application[] | ."@name" as $name |
    .service.serviceInstance[]  | [ $name, .machine, .status ] | @csv' file.xml

답변4

xml 도구를 사용하지 않는 타당한 이유가 있는 경우 애플리케이션이 예제처럼 사소하게 유지되는 한 낮은 수준 구문 분석을 사용할 수 있습니다.

sed 's/<application name="\([^"]*\)">/\1/
Ta
h
d
:a
/<machine>/!d
G
N
s_.*<machine>\(.*\)</machine>\n\(.*\)\n.*<status>\(.*\)</status>.*_\2,\1,\3_' yourfile.xml

관련 정보