[英]How can I iterate through different items in xml output and then print out different values for each item using bash/linux shell commands
I have the following XML output (produced by using curl to create a SOAP call to a WSDL): 我有以下XML输出(使用curl创建对WSDL的SOAP调用产生):
<?xml version="1.0"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<ns1:getNodesResponse xmlns:ns1="http://node.sdk.nms.ov.hp.com/">
<return>
<item>
<created>2013-04-22T12:48:06.676Z</created>
<deviceCategory>com.hp.ov.nms.devices.switchrouter</deviceCategory>
<deviceDescription>Cisco Nexus C7018 DataCenter Switch</deviceDescription>
<deviceFamily>com.hp.ov.nms.devices.cisconexus7000seriesswitches</deviceFamily>
<deviceModel>ciscoNexusC7018</deviceModel>
<deviceVendor>com.hp.ov.nms.devices.cisco</deviceVendor>
<discoveryState>DISCOVERY_COMPLETED</discoveryState>
<systemContact>xxxxxxxxxxxxxxxxxxx</systemContact>
<systemDescription>xxxxxxxxxxxxxxxxxxxx</systemDescription>
<systemLocation>xxxxxxxxxxxxxxxxxx</systemLocation>
<systemName>xxxxxxxxxxxxxxxxxxx</systemName>
<systemObjectId>.1.3.6.1.4.1.9.12.3.1.3.777</systemObjectId>
<uuid>c8652440-caf2-490b-8892-cb914a39d19e</uuid>
</item>
<item>
<created>2013-04-22T12:49:36.750Z</created>
<deviceCategory>com.hp.ov.nms.devices.switchrouter</deviceCategory>
<deviceDescription>Cisco Nexus C7018 DataCenter Switch</deviceDescription>
<deviceFamily>com.hp.ov.nms.devices.cisconexus7000seriesswitches</deviceFamily>
<deviceModel>ciscoNexusC7018</deviceModel>
<deviceVendor>com.hp.ov.nms.devices.cisco</deviceVendor>
<discoveryState>DISCOVERY_COMPLETED</discoveryState>
<systemContact>xxxxxxxxxxxxxxxxx</systemContact>
<systemDescription>xxxxxxxxxxxxxxxxxx</systemDescription>
<systemLocation>xxxxxxxxxxxxxx</systemLocation>
<systemName>xxxxxxxxxxxxxxxxxx</systemName>
<systemObjectId>.1.3.6.1.4.1.9.12.3.1.3.777</systemObjectId>
<uuid>6f5ef089-6a51-459f-bde1-9cf18e4f8ca7</uuid>
</item>
<item>
<created>2013-04-22T12:51:56.872Z</created>
<deviceCategory>com.hp.ov.nms.devices.switchrouter</deviceCategory>
<deviceDescription>Cisco Nexus C7018 DataCenter Switch</deviceDescription>
<deviceFamily>com.hp.ov.nms.devices.cisconexus7000seriesswitches</deviceFamily>
<deviceModel>ciscoNexusC7018</deviceModel>
<deviceVendor>com.hp.ov.nms.devices.cisco</deviceVendor>
<discoveryState>DISCOVERY_COMPLETED</discoveryState>
<systemContact>xxxxxxxxxxxxxxxxxx</systemContact>
<systemDescription>xxxxxxxxxxxxxxxxxxxxxxxxx</systemDescription>
<systemLocation>xxxxxxxxxxxxxxxxxxx</systemLocation>
<systemName>xxxxxxxxxxxxxxxxxxx</systemName>
<systemObjectId>.1.3.6.1.4.1.9.12.3.1.3.777</systemObjectId>
<uuid>bae02b8c-25d4-4b53-bef0-2d5b14536e0b</uuid>
</item>
</item>
</return>
</ns1:getNodesResponse>
</env:Body>
</env:Envelope>
How could I go about iterating through each <item>
and then for each item, print out different values for the item? 如何遍历每个<item>
,然后为每个项目打印出该项目的不同值? I was thinking about just grepping for <item>
s and then picking through the data between every <item>
and </item>
, but I was not sure if there was a better way to do this. 我当时只是想为<item>
grep处理,然后在每个<item>
和</item>
之间挑选数据,但是我不确定是否有更好的方法。 I would be using bash/linux shell commands 我将使用bash / linux shell命令
Pseudo code: 伪代码:
for i in item
print i.uuid,i.systemName
It's better to use a xml parser or xml querying language instead of regex and bash commands. 最好使用xml解析器或xml查询语言代替regex和bash命令。 If you are programming in some language see DOM
, SAX
, StAX
etc based xml parsers. 如果您使用某种语言进行编程,请参阅基于DOM
, SAX
, StAX
等的xml解析器。 You can also use SQL like syntax for xml by using XQuery
; 您还可以通过使用XQuery
对xml使用类似SQL的语法。 another language to get your data can be xpath
. xpath
是获取数据的另一种语言。
http://www.w3schools.com/xsl/xpath_intro.asp http://www.w3schools.com/xsl/xpath_intro.asp
http://www.w3schools.com/xsl/xquery_intro.asp http://www.w3schools.com/xsl/xquery_intro.asp
But if you still insist using bash tools.. here is a sed
1-liner: 但是,如果您仍然坚持使用bash工具,那么这里是sed
1-liner:
$ sed -n -e '/<item>/,/<\/item>/p' xml | sed -r -e 's/^\s*<uuid>(.*)<\/uuid>/\1/g' -e 's/^\s*<systemName>(.*)<\/systemName>/\1/g' -e '/^\s*</d' | sed -n 'N;s/\n/,/g;p'
xxxxxxxxxxxxxxxxxxx,c8652440-caf2-490b-8892-cb914a39d19e
xxxxxxxxxxxxxxxxxx,6f5ef089-6a51-459f-bde1-9cf18e4f8ca7
xxxxxxxxxxxxxxxxxxx,bae02b8c-25d4-4b53-bef0-2d5b14536e0b
$
Breakdown: 分解:
sed -n -e '/<item>/,/<\\/item>/p' xml
sed -r -e 's/^\\s*<uuid>(.*)<\\/uuid>/\\1/g' -e
's/^\\s*<systemName>(.*)<\\/systemName>/\\1/g' -e '/^\\s*</d'
sed -n 'N;s/\\n/,/g;p'
Expression 1: suppress default printing, and p
(print) lines with a range. 表达式1:禁止默认打印,并且p
(打印)行具有一定范围。 start line should be match regex <item>
and end line must match regex </item>. This gives you all items
起始行应与regex <item>
相匹配,而结束行必须与regex </item>. This gives you all items
相匹配</item>. This gives you all items
</item>. This gives you all items
...`. </item>. This gives you all items
。
Expression 2: Now we strip off the tags <uuid>
, </uuid>
, <SystemName>
, </SystemName>
and just keep the inner portion using regex and s
(substitute) command. 表达式2:现在我们剥离标签<uuid>
, </uuid>
, <SystemName>
, </SystemName>
然后仅使用regex和s
(替代)命令保留内部。
Expression 3: Suppressed default printing( -n
); 表达式3:禁止默认打印( -n
); N
reads next line from input and concatenates it to previous line(already read by sed into pattern space); N
从输入中读取下一行并将其连接到上一行(已经通过sed读入模式空间); therefore concatenating consecutive lines separated by a newline \\n
. 因此,将由换行符\\n
分隔的连续行串联起来。 Then we substitute the \\n
char with comman and print the pattern space( p
). 然后,将\\n
char替换为comman并打印模式空间( p
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.