简体   繁体   English

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

[英]read and concatenate xml attributes using shell script

I have an xml: 我有一个xml:

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

I need to get an output like below, using shell script: 我需要使用shell脚本获得如下输出:

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

awk -F'attr1 =“ | attr3 =” |“''{print $ 2”(“ $(NF-1)”)“}'文件

The right way to extract contents from XML is with a real, live XML parser. 从XML提取内容的正确方法是使用真实的实时XML解析器。 XMLStarlet is onesuch. XMLStarlet就是这样。

Note that this requires your data to be actual XML , which your existing data isn't without a root element being added. 请注意,这要求您的数据是实际的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

To explain how this works: 解释这是如何工作的:

  • -t starts a new template -t启动一个新模板
  • -m //element matches an element named element anywhere in your document. -m //element匹配文档中任何位置的名为element
  • -v ./@attr1 emits the content of the attribute named attr1 -v ./@attr1发出名为attr1的属性的内容
  • -o '(' emits a literal ( as a string -o '('发出文字(作为字符串
  • -v ./@attr3 emits the content of the attribute named attr3 -v ./@attr3发出名为attr3的属性的内容
  • -o ')' emits a literal ) as a string -o ')'发出文字)作为字符串
  • -n emits a literal newline -n发出文字换行符

If you want to be able to run this on machines that don't have XMLStarlet installed, you can generate an XSLT template, and invoke that with XSLTProc, which is widely available. 如果您希望能够在未安装XMLStarlet的计算机上运行此程序,则可以生成XSLT模板,然后使用广泛使用的XSLTProc调用该模板。

Running xmlstarlet sel -C -t -m '//element' -v ./@attr1 -o '(' -v ./@attr3 -o ')' -n emits the following XSLT file: 运行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>

If you save this as myproc.xslt , and run xsltproc myproc.xslt - <input.xml , you'll get the desired output on stdout. 如果将其另存为myproc.xslt并运行xsltproc myproc.xslt - <input.xml ,则将在stdout上获得所需的输出。

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)

you can also use sed as below; 您还可以按以下方式使用sed;

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

Example; 例;

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

OR.. we can do this with perl.. OR ..我们可以用perl来做到这一点。

Tested on CentOS7 在CentOS7上测试

cat your file to this filter as shown below... 将您的文件指向此过滤器,如下所示...

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>

awk -F'[="]' '{print $3 "("$(NF-1)")"}' file awk -F'[=“]''{print $ 3”(“ $(NF-1)”)“}'文件

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM