如何在shell脚本中计算平均值时处理缺失值?

时间:2015-06-19 02:51:22

标签: linux shell unix awk

我有一个包含许多缺失值的数据集为双斜杠(//)。部分数据是

input.txt
30
//
10
40
23
44
//
//
31
//
54
// and so on

我想在不考虑缺失值的情况下计算每6行间隔的平均值。我正在尝试这个,但没有得到我需要的东西。

awk '{if ($1 -ne "//") sum += $1} (NR%6)==0 {print(sum/NR)}' input.txt

正在给予

24.5
19.33

但答案应该来了

29.4
42.5

1 个答案:

答案 0 :(得分:3)

您需要稍微修改awk以获得输出

$ awk '!/\//{sum += $1; count++} NR%6==0{print sum/count;sum=count=0}'

<强>测试

$ awk '!/\//{sum += $1; count++} NR%6==0{print sum/count;sum=count=0}' file
29.4
42.5

它的作用是什么?

  • !/\//{sum += $1; count++}

    • !/\//模式检查该行是否包含/

    • {sum += $1; count++}当该行不包含/时,会执行此操作,该列将第1列$1sum相加并增加count 1}}基本上告诉我们在下次打印之前已经看到了多少位awk

  • NR%6==0{print sum/count;sum=count=0}当记录数量NR6的倍数时,我们打印平均值sum/count并重置countsum变量。

修改

要打印最后一组可能小于6的行,我们可以使用END块作为

$ awk '!/\//{sum += $1; count++} NR%6==0{print sum/count;sum=count=0} END{print sum/count}' file
29.4
42.5
  • END{print sum/count}' END块将在文件结束时更新。

修改2

边缘情况当6行中没有数字出现时,上面的脚本会导致除以零错误。 print语句可以格式化以处理这种情况。

print count ? (sum/count) : count;sum=count=0}
  • 这是一个基本的三元运算符,它检查计数是否为非零,如果是,则打印分割值,否则打印count,0

<强>测试

$ awk '!/\//{sum += $1; count++} NR%6==0{print count ? (sum/count) : count;sum=count=0}' file
29.4
42.5
0