0

我有一个<Amt Ccy="EUR">3.1</Amt Ccy="EUR">标签重复的 XML。这(Ccy 可能会有所不同)在另一个标签下<Main>。我需要对仅使用 awk 和/或 sed 命令的所有值求和<Amt Ccy="EUR">(Ccy 可能会有所不同) 。<Main>

可以帮忙吗?

示例如下所示

<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>
4

6 回答 6

1

您的描述与提供的示例文件之间存在一些不一致之处,并且您的 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
于 2012-12-26T15:39:56.710 回答
1
echo "cat /root//Amt" |                            \
    xmllint --shell input.xml |                    \
    sed -n '/EUR/{s/[^>]*> *\([0-9.]*\).*/\1/p}' | \
    awk '{sum+=$1} END{print sum;}'
于 2012-12-27T07:38:51.597 回答
0

通常,当需要查找 XML 文件时,最好使用 XML 解析器。

但是,如果您的文件足够简单,并且<Amt Ccy="EUR">...</Amt>每行仅包含一个而没有其他内容:

awk -F "[<>]" '$0 ~ "^[ \t]*<Amt Ccy=\"EUR\">.*</Amt>" { sum += $3}
               END { print sum }' your_file

我正在做的是

  • 仅选择以 0 个或多个空格/制表符开头并匹配您的特定标签的行,
  • 使用<and>作为字段分隔符,您的金额是字段编号 3,
  • 将所有选定行中的金额相加,
  • 在脚本末尾打印总和。
于 2012-12-26T15:48:00.657 回答
0

鉴于以下数据

$ 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 命令解析出 Euro "Amt" XML 标记的值,使用 Xpath 表达式。然后将结果集与 awk 相加。

使用 Xpath 是处理 XML 的更原生的方式。

于 2012-12-27T12:27:14.687 回答
0

如果 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 数组/哈希映射键的基础。

于 2014-09-19T02:12:56.647 回答
0

也许有人会发现以下方法很有用。

有一个 xpath sum()函数可用于避免使用 xmllint 以外的工具来总结结果:

echo "xpath sum(///Amt[@Ccy='EUR'])"|xmllint --shell data.xml
于 2015-08-19T11:32:40.937 回答