如何使用awk计算一天内重复记录的平均值?

时间:2016-12-17 14:59:13

标签: awk

有人能告诉我如何使用awk计算每天($ 2)重复记录的平均值,使用数据集的唯一ID($ 1)和测量($ 3)记录。  数据集如下所示:

32070     2010-12-15    540  
32070     2010-12-15    546  
32070     2010-12-15    549  
32070     2010-12-17    579  
32070     2010-12-17    553  
25903     2010-12-15    556  
25903     2010-12-15    543  
25903     2010-12-15    564  
25903     2010-12-16    567  
25903     2010-12-16    583 

我想根据每个唯一ID($ 1)的测量值($ 3)获得每天平均记录($ 2)并分别打印输出文件,如下所示:

32070  2010-12-15    545  
32070  2010-12-17    566  
25903  2010-12-15     554.33  
25903  2010-12-16     575  

2 个答案:

答案 0 :(得分:2)

$ cat tst.awk
{ curr = $1 OFS $2 }
curr != prev { if (cnt) print prev, sum / cnt; sum=cnt=0 }
{ sum+=$3; cnt++; prev=curr }
END { if (cnt) print prev, sum / cnt }

$ awk -f tst.awk file
32070 2010-12-15 545
32070 2010-12-17 566
25903 2010-12-15 554.333
25903 2010-12-16 575

这和@Ruslans答案的区别在于:

  1. 他将整个输入文件存储在内存中,而上面只将4个变量(curr,prev,sum和cnt)的值存储在内存中。
  2. 他输出的结果是随机的(实际上是大多数awk实现中的哈希)顺序,而上面按照它们在输入中出现的顺序输出结果。
  3. 无论你输入的顺序是什么,他都会工作,而上述依赖于你的输入按id和日期排序。

答案 1 :(得分:0)

BEGIN { SUBSEP = "@" }

{ a[$1,$2] += $3; n[$1,$2]++ }

END {
  for (x in a) {
    split(x, parts, SUBSEP)
    print parts[1] " " parts[2] " " a[x] / n[x]
  }
}

输出

25903 2010-12-15 554.333
25903 2010-12-16 575
32070 2010-12-15 545
32070 2010-12-17 566

<强>解释

SUBSEP是一个内部变量,用于分隔multidimensional arrays中的键。其默认值为"\034",不太可能出现在输入中。我在调试时将其设置为@。您可以跳过修改此变量。

与“预期输出”相比,输出的顺序不同。但您可以使用sort工具按列轻松对其进行排序。例如,以下内容将按第二列对输出进行排序,然后按第一列(按此顺序)排序:

awk -f script.awk file | sort -k2 -k1g

输出

25903 2010-12-15 554.333
25903 2010-12-16 575
32070 2010-12-15 545
32070 2010-12-17 566

这只是一个样本。你应该有一般的想法。根据需要修改命令。