[英]awk and or sed command to sum the value in repeating tags in a XML
我有一个XML,其中<Amt Ccy="EUR">3.1</Amt Ccy="EUR">
标签重复。 这(Ccy可能会有所不同)在另一个标签<Main>
。 我需要总结<Amt Ccy="EUR">
(Ccy可能会有所不同)的所有值,只能在<Main>
使用awk和/或sed命令。
可以帮一些忙吗?
示例如下所示
<root>
<Main>
<someothertag>..</someothertag>
<Amt Ccy="EUR">3.1</Amt>
</Main>
.
.
.
some other tags
<Main>
<someothertag>..</someothertag>
<Amt Ccy="SGD">51</Amt>
</Main>
<another>
<Amt Ccy="EUR">10</Amt>
</another>
</root>
您的描述与提供的示例文件之间存在一些不一致,以及xml文件中的一些技术错误。 以下是我认为您正在寻找使用awk
:
awk '/<Main>/ { f=1 } f && /Amt/ { split($0,a,/[<>]/); s+=a[3] } /<\/Main>/ { f=0 } END { print "The sum is:", s }' file
结果
The sum is: 54.1
请注意,我使用的正则表达式可能需要调整,具体取决于您的输入。 如果上述脚本失败,请考虑使用更多样本数据和预期输出编辑您的问题。 然后我们将能够进一步帮助您。 此外,根据注释,您可能需要考虑为此作业使用适当的xml解析器。
编辑:
从下面的评论中,以下内容应计算不同货币的总和,这些货币必须在<Main>
和</Main>
标签内。
awk '/<Main>/ { f=1 } f && /<Amt.*Amt>/ { split($0,a,/[<>"]/); b[a[3]]+=a[5] } /<\/Main>/ { f=0 } END { for (i in b) printf "The sum of %s is: %s\n", i, b[i] | "sort" }' file
结果:
The sum of EUR is: 3.1
The sum of SGD is: 51
echo "cat /root//Amt" | \
xmllint --shell input.xml | \
sed -n '/EUR/{s/[^>]*> *\([0-9.]*\).*/\1/p}' | \
awk '{sum+=$1} END{print sum;}'
通常,在需要搜索XML文件时,最好使用XML解析器。
但是如果你的文件很简单,并且每行只包含一个<Amt Ccy="EUR">...</Amt>
而没有别的:
awk -F "[<>]" '$0 ~ "^[ \t]*<Amt Ccy=\"EUR\">.*</Amt>" { sum += $3}
END { print sum }' your_file
我在做什么
<
和>
作为字段分隔符,您的金额为字段编号3, 鉴于以下数据
$ cat data.xml
<root>
<Main>
<someothertag>..</someothertag>
<Amt Ccy="EUR">3.1</Amt>
</Main>
<Main>
<someothertag>..</someothertag>
<Amt Ccy="SGD">51</Amt>
</Main>
<another>
<Amt Ccy="EUR">10</Amt>
</another>
</root>
下列
$ echo "cat ///Amt[@Ccy='EUR']/text()" | xmllint --shell data.xml | awk '{s+=$1} END{print s}'
13.1
使用xmllint命令使用Xpath表达式解析Euro“Amt”XML标记的值。 然后结果集由awk求和。
使用Xpath是处理XML的更原生的方式。
如果gawk可用,您可以使用记录分隔符模式来匹配XML标记。 下面的模式匹配以<开头的内容,后跟不是>一次或多次的字符,并以>结尾。 当gawk与RS匹配时,它会将匹配的文本分配给RT。 这为我们提供了一种匹配标记,检查标记并处理它们之间嵌入的值的方法。
gawk '
BEGIN { RS="<[^>]+>" }
RT == "</Amt>" {
if (previousTag ~ "EUR") { eTotal += $0 }
}
{ previousTag = RT; }
END { print eTotal }' myFile
对于给定的样本,上面将打印出13.1。 如果我们想要对每种货币求和,则可以使用previousTag作为awk数组/ hashmap键的基础。
也许有人会发现以下方法有用。
有xpath sum()函数,可以用来避免使用xmllint以外的工具来总结结果:
echo "xpath sum(///Amt[@Ccy='EUR'])"|xmllint --shell data.xml
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.