awk分组和列表值的总和

时间:2015-12-17 17:10:39

标签: awk grouping

关于awk(bash)的问题,要求对每个项目的值求和。输入文件如下:

    item      value
    ----------------
    item1     8
    item1     1
    item1     5
    item2     2
    item2     8
    item3     4
    item3     7
    item3     7
    Timely Total    xxx

    item1   5  
    item1   4 
    item1   3
    item2   4
    item2   1
    Timely Total   17 

我的问题: 要对每个项目求和,我有代码:

 awk '{a[$1]+=$2}END{for(i in a) print i, "has", a[i], "entries" }'

没关系,但是它会在所有Timelytotals中为所有item1的整个文件求和

我需要:Timely total1中item1的总和,Timely total1中item2的总和,Timely total1中item3的总和,然后 timely total2中item1的总和,Timely total2中item2的总和,Timely total2中item3的总和。 类似于更及时的总计。

2 个答案:

答案 0 :(得分:3)

您还没有真正说出输出应该是什么样子,所以任何答案在某种程度上都是猜测。这是我的猜测。

script.awk

NR < 3 { print; next }
$1 == "Timely" {
    for (a in sum)
    {
        print "Subtotal", a, sum[a]
    }
    print "Timely Total ", total
    total = 0;
    delete sum
    next
}
$1 == "" { print; next }
{
    sum[$1] += $2
    total += $2
    print
}

第一行打印两个标题行。

&#39;及时&#39;块打印累积的数据(假设有一些要打印)。对于显示的每个项目,它会打印相应的总和以及标识信息。然后它会打印一个“及时总计”&#39;整个街区。然后通过删除sum数组并将total归零来为统计数据清零,为下一组数据做好准备。

打印$1 == ""块,否则忽略空行。

默认块累计项目和总和的总和并打印该行。

显然,如果您不想要各个数据行,则省略最后一个print。同样清楚的是,你可以用你喜欢的任何格式打印小计(实际上是总数) - printf函数在这里很有用。如果您不打印各行,则可能会跳过两个标题行而不是打印它们。可以进行无休止的调整,但在没有相反信息的情况下,我相信这提供了一个合理的答案,可以很容易地适应所需的输出格式。

需要注意的一点是:样本数据最终按顺序打印了项目小计,但这很可能是偶然而非保证的行为。如果重要的话,有办法解决这个问题。但是,有多种方法可以实现,GNU Awk内置了额外的功能,可以帮助其他Awk变体需要手动编码。

示例输出

$ awk -f script.awk data
item      value
----------------
item1     8
item1     1
item1     5
item2     2
item2     8
item3     4
item3     7
item3     7
Subtotal item1 14
Subtotal item2 10
Subtotal item3 18
Timely Total  42

item1   5  
item1   4 
item1   3
item2   4
item2   1
Subtotal item1 12
Subtotal item2 5
Timely Total  17
$

答案 1 :(得分:0)

祝贺一个详细的问题,并解释你想要完成的事情。一种方法是使用$ 1以外的东西作为关联数组的关键。由于在整个领域中没有任何东西看起来像一把钥匙,你可以保留一个计数器,看看你已经看过多少次&#34;及时&#34;之前并为每一个增加它。

$awk 'BEGIN {timely=1;} /^item[0-9]+/ {a[timely "-" $1]+=$2} /^Timely.*/ {timely+=1} END {for(i in a) print i,"has" ,a[i] " entries" }' < t | sort
1-item1 has 14 entries
1-item2 has 10 entries
1-item3 has 18 entries
2-item1 has 12 entries
2-item2 has 5 entries

关键部分是a[timely "-" $1]+=$2,它将总数存储在单独的&#34;存储桶&#34;每次找到新的/^Timely.*/时。