使用shell脚本读取和连接xml属性

时间:2016-10-03 10:27:18

标签: xml shell

我有一个xml:

<element attr1="val11" attr2="val12" attr3="val13" />
<element attr1="val21" attr2="val22" attr3="val23" />
<element attr1="val31" attr2="val32" attr3="val33" />

我需要使用shell脚本获得如下所示的输出:

val11(val13)
val21(val23)
val31(val33)

6 个答案:

答案 0 :(得分:1)

awk -F&#39; attr1 =&#34; | attr3 =&#34; |&#34; &#39; &#39; {print $ 2&#34;(&#34; $(NF-1)&#34;)&#34; }&#39;文件

答案 1 :(得分:1)

从XML中提取内容的正确方法是使用真实的实时XML解析器。 XMLStarlet就是那样。

请注意,这需要您的数据实际XML ,您的现有数据并非没有添加根元素。

xmlstarlet sel -t -m '//element' -v ./@attr1 -o '(' -v ./@attr3 -o ')' -n <<EOF
<root>
<element attr1="val11" attr2="val12" attr3="val13" />
<element attr1="val21" attr2="val22" attr3="val23" />
<element attr1="val31" attr2="val32" attr3="val33" />
</root>
EOF

解释这是如何工作的:

  • -t启动新模板
  • -m //element在您的文档中的任何位置匹配名为element的元素。
  • -v ./@attr1会发出名为attr1
  • 的属性的内容
  • -o '('以字符串
  • 的形式发出文字(
  • -v ./@attr3会发出名为attr3
  • 的属性的内容
  • -o ')'以字符串
  • 的形式发出文字)
  • -n会发出文字换行符

如果您希望能够在未安装XMLStarlet的计算机上运行此程序,则可以生成XSLT模板,并使用广泛可用的XSLTProc调用该模板。

运行xmlstarlet sel -C -t -m '//element' -v ./@attr1 -o '(' -v ./@attr3 -o ')' -n会发出以下XSLT文件:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
  <xsl:output omit-xml-declaration="yes" indent="no"/>
  <xsl:template match="/">
    <xsl:for-each select="//element">
      <xsl:call-template name="value-of-template">
        <xsl:with-param name="select" select="./@attr1"/>
      </xsl:call-template>
      <xsl:text>(</xsl:text>
      <xsl:call-template name="value-of-template">
        <xsl:with-param name="select" select="./@attr3"/>
      </xsl:call-template>
      <xsl:text>)</xsl:text>
      <xsl:value-of select="'&#10;'"/>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="value-of-template">
    <xsl:param name="select"/>
    <xsl:value-of select="$select"/>
    <xsl:for-each select="exslt:node-set($select)[position()&gt;1]">
      <xsl:value-of select="'&#10;'"/>
      <xsl:value-of select="."/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

如果将其保存为myproc.xslt,并运行xsltproc myproc.xslt - <input.xml,则会在stdout上获得所需的输出。

答案 2 :(得分:0)

awk '{split($2,a,"=");split($4,b,"=");gsub(/"/,"",a[2]);gsub(/"/,"",b[2]);print a[2]"("b[2] ")"}' xml
val11(val13)
val21(val23)
val31(val33)

答案 3 :(得分:0)

你也可以使用如下的sed;

sed 's/^.*1="//g;s/" .*.="/(/;s/" \/>/)/g' yourXMl

实施例

user@host:/tmp$ sed 's/^.*1="//g;s/" .*.="/(/;s/" \/>/)/g' t1
val11(val13)
val21(val23)
val31(val33)

答案 4 :(得分:0)

或..我们可以用perl做这个..

在CentOS7上测试

将您的文件捕获到此过滤器,如下所示...

Tue Oct 04|22:41:36|gaurav@[STATION]:/root/ga/scripts/temp> cat c.txt
<element attr1="val11" attr2="val12" attr3="val13" />
<element attr1="val21" attr2="val22" attr3="val23" />
<element attr1="val31" attr2="val32" attr3="val33" />
Tue Oct 04|22:41:38|gaurav@[STATION]:/root/ga/scripts/temp> cat c.txt |perl -pe 's/^.+r1=\"(.+?)\".+r3=\"(.+?)\" .*$/\1(\2)/g'
val11(val13)
val21(val23)
val31(val33)
Tue Oct 04|22:41:40|gaurav@[STATION]:/root/ga/scripts/temp>

答案 5 :(得分:0)

awk -F&#39; [=&#34;]&#39; &#39; {print $ 3&#34;(&#34; $(NF-1)&#34;)&#34;}&#39;文件

val11(val13)
val21(val23)
val31(val33)