繁体   English   中英

awk和/或sed命令用于对XML中重复标记的值求和

[英]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

我在做什么

  • 仅选择以0或更多空格/制表符开头并与您的特定标签匹配的行,
  • 使用<>作为字段分隔符,您的金额为字段编号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.

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