使用awk计算CSV数据平均值结果错误,问题出在哪里?
问题排查:awk计算estimate列平均值出错
问题背景
现有如下CSV格式的家务数据,目标是用awk计算estimate列的平均值:
$ cat chores.csv Chore Name,Assigned to,estimate,done? Laundry,Chelsey,45,N Wash Windows,Sam,60,Y Mop kitchen,Sam,20,N Clean cookware,Chelsey,30,N Unload dishwasher,Chelsey,10,N Dust living room,Chelsey,20,N Wash the dog,Sam,40,N
编写的awk脚本如下:
#!/bin/awk BEGIN { NR>1 FS="," } $3 > 0 { i++ ; tot+=$3 avg=tot/i } END{ printf "\nAverage: %.2f\n ", avg }
运行后得到错误输出:
awk -f avg.awk chores.csv Average: 28.12
而正确平均值应为32.14,以下是问题排查及修正方案:
错误原因分析
NR>1的位置错误
你把跳过表头的判断NR>1写在了BEGIN块中,但BEGIN块是在处理任何数据行之前执行的,此时行号NR的值为0,这行代码完全起不到跳过表头的作用。虽然表头行的$3是字符串estimate,会被awk转为数值0,不满足$3>0的条件,但结合其他问题会导致统计错误。字段分隔符设置有误
脚本中的FS=","是HTML转义后的写法,若实际编写时误用了中文双引号(“”)或引号格式错误,会导致FS(字段分隔符)未被正确设置为英文逗号,进而导致字段分割错误——$3不再指向estimate列,甚至可能误将表头的某部分当作数值计入统计,最终让计数和总和出错。循环内重复计算平均值无意义
你在每一次循环中都计算avg=tot/i,这步操作完全多余,只需要在END块中计算一次即可,不过这不会直接导致结果错误。
修正后的脚本
#!/bin/awk BEGIN { FS="," # 使用英文双引号设置字段分隔符为逗号 } NR>1 && $3+0>0 { # 跳过表头行,同时确保$3是有效数字 i++ tot+=$3 } END { if(i>0) { # 避免出现除以0的异常 printf "\nAverage: %.2f\n", tot/i } else { printf "\nNo valid data to calculate average.\n" } }
验证结果
运行修正后的脚本:
awk -f avg.awk chores.csv
输出:
Average: 32.14
内容的提问来源于stack exchange,提问作者CatScratch
相关产品推荐
相关产品推荐

