我的日志文件如下所示:
<lun compNum="3" partitionNum="1" failed="1" backup="1" free_mem="1024" max_mem="2048" />
<lun compNum="22" partitionNum="11" failed="1" backup="0" free_mem="1024" max_mem="2048" />
我想要一个输出遍历所有这些行并将compNum
和paritionNum
保存到此中:
PAIR=($compNumValue parititonNumValue)
不使用任何外部库并且仅使用本机bash的解决方案将是理想的。知道如何开始为bash的新手开始吗?
答案 0 :(得分:4)
lun_re='<lun compNum="([[:digit:]]+)" partitionNum="([[:digit:]]+)"[^/]* />'
while IFS= read -r line; do
if [[ $line =~ $lun_re ]]; then
compNum=${BASH_REMATCH[1]}
partitionNum=${BASH_REMATCH[2]}
echo "Read a line with compNum $compNum and partitionNum $partitionNum"
fi
done
请参阅:
BASH_REMATCH
和[[ $string =~ $regex ]]
在读取XML时使用XML解析器。 <强>真即可。其他任何东西都不知道如何处理注释,命名空间,CDATA部分,甚至是简单的更改,比如生成此日志的程序的新版本将所有元素放在同一行上(或者在属性之间添加换行符,甚至只是更改属性以使partitionNum
之前有partNum
。
在这种情况下,可能如下所示:
while IFS='|' read -r -d '' compNum partitionNum; do
echo "Read a line with compNum $compNum and partitionNum $partitionNum"
done < <(xmlstarlet sel -t -m '//lun[@compNum][@partitionNum]' \
-v ./@compNum -o '|' \
-v ./@partitionNum -n)
除了上面给出的链接之外,请参阅BashFAQ #24以了解正在使用< <(...)
语法的原因。
如果您没有在运行它的系统上安装XMLStarlet,您可以生成XSLT模板并使用xsltproc
对其进行评估。 xmlstarlet -C
发出以下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="//lun[@compNum][@partitionNum]">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="./@compNum"/>
</xsl:call-template>
<xsl:text>|</xsl:text>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="./@partitionNum"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</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()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
...这样您就可以使用xsltproc /path/to/template.xslt -
作为给定xmlstarlet
命令的等效内容。