awk数组均值计算问题:按列非空字段数而非KEY计数求平均
解决awk按KEY计算列平均值(按列非空计数)的问题
针对你遇到的问题,核心是需要为每列单独维护非空字段的计数,而非统一使用KEY的总出现次数。以下是修改后的awk命令,同时适配你提到的14列场景的扩展思路:
修改后的awk命令
awk -F ';' -v OFS=";" ' NR > 1 { # 跳过表头行 key = $5 arrkey[key]++ # 记录KEY总出现次数(对应输出第二列) # 处理HPA列:非空则累加总和与计数 if ($2 != "") { HPA_sum[key] += $2 HPA_cnt[key]++ } # 处理TGK列:非空则累加总和与计数 if ($3 != "") { TGK_sum[key] += $3 TGK_cnt[key]++ } # 处理DIU列:非空则累加总和与计数 if ($4 != "") { DIU_sum[key] += $4 DIU_cnt[key]++ } # 14列场景:按相同格式继续添加其他列的处理逻辑即可 } END { for (a in arrkey) { # 计算各列平均值,计数为0时可设为0或空(按需调整) hpa_avg = HPA_cnt[a] ? HPA_sum[a]/HPA_cnt[a] : 0 tgk_avg = TGK_cnt[a] ? TGK_sum[a]/TGK_cnt[a] : 0 diu_avg = DIU_cnt[a] ? DIU_sum[a]/DIU_cnt[a] : 0 # 输出格式:KEY;总次数;HPA平均值;TGK平均值;DIU平均值 print a, arrkey[a], hpa_avg, tgk_avg, diu_avg } }' infile > outfile
关键修改点说明
- 列独立计数:为每个列创建
*_sum(总和)和*_cnt(非空计数)数组,仅当对应字段非空时才更新这两个数组,确保平均值计算的分母是该列实际有值的行数。 - 跳过表头:用
NR>1跳过第一行表头,避免表头干扰数值计算。 - 防除以0:计算平均值前先判断计数是否大于0,避免空字段导致的运行错误(可根据需求改为输出空字符串)。
- 全量处理行:移除原命令中
+$2 +$3 +$4的限制条件,确保每行都被处理,不管哪些字段为空。
验证结果
运行修改后的命令后,针对你的测试数据,输出将与期望完全一致:
49_08_1975;5;945.65;-0.2;4.22 49_08_1976;2;927.05;2.55;2.95
14列场景扩展建议
如果需要处理14列,只需重复上述列处理逻辑:为每一列添加对应的*_sum和*_cnt数组判断与累加,最后在END块中依次计算每列的平均值并追加到输出行即可。
内容的提问来源于stack exchange,提问作者anlom
相关产品推荐
相关产品推荐

