修改Bash脚本补0至指定行数以修正统计偏差
问题描述
我有一段用于计算平均值、标准差、中位数、最小值和最大值的命令行代码:
cut -f3 $file | sort -n | awk 'BEGIN {c = 0; sum = 0;} $1 ~ /^(\-)?[0-9]*(\.[0-9]*)?$/ {a[c++] = $1; sum += $1; sumsq+=$1*$1} END {ave = sum / c; if( (c % 2) == 1 ) { median = a[ int(c/2) ]; } else {median = ( a[c/2] + a[c/2-1] ) / 2; } OFS="\t"; sd = sqrt(sumsq/c - (sum/c)**2); print ave, sd, median, a[0], a[c-1]; }' >> $output
每个文件应包含772474283行,但很多文件不满足该条件,导致统计结果出现偏差。因此我需要在提取第三列后补充0值,使总行数达到指定数量,让0参与平均值、标准差等统计计算。我考虑先通过wc -l计算文件行数,再补充X个0(X=772474283-现有行数),请问该如何实现?或者有没有更优雅的方法?
解决方案
方案一:按分步思路实现
先提取第三列并过滤有效数字行,统计行数后补充对应数量的0,再执行统计:
# 定义目标总行数 TARGET=772474283 # 临时文件存储有效数字行 tmp_file=$(mktemp) cut -f3 "$file" | awk '$1 ~ /^(\-)?[0-9]*(\.[0-9]*)?$/' > "$tmp_file" # 计算当前有效行数和需要补充的0的数量 current_lines=$(wc -l < "$tmp_file") add_lines=$((TARGET - current_lines)) # 补充0并执行统计流程 cat "$tmp_file" \ | awk -v n="$add_lines" 'BEGIN{for(i=0;i<n;i++) print 0} {print}' \ | sort -n \ | awk 'BEGIN {c = 0; sum = 0; sumsq=0} {a[c++] = $1; sum += $1; sumsq+=$1*$1} END { ave = sum / c; if( (c % 2) == 1 ) { median = a[ int(c/2) ]; } else { median = ( a[c/2] + a[c/2-1] ) / 2; } OFS="\t"; sd = sqrt(sumsq/c - (sum/c)**2); print ave, sd, median, a[0], a[c-1]; }' >> "$output" # 清理临时文件 rm "$tmp_file"
注意:这里先过滤非数字行再统计行数,确保补充的0是基于有效数据的数量计算,和原逻辑保持一致。
方案二:一站式awk处理(更高效优雅)
将提取第三列、过滤数字、补充0、统计逻辑合并到一个awk脚本中,仅扫描文件一次,大幅提升大文件处理效率:
TARGET=772474283 awk -v target="$TARGET" -F'\t' ' BEGIN {c = 0; sum = 0; sumsq=0} # 处理第三列的有效数字行 $3 ~ /^(\-)?[0-9]*(\.[0-9]*)?$/ { a[c++] = $3; sum += $3; sumsq += $3*$3; } END { # 计算需要补充的0的数量 add = target - c; # 把0纳入统计总和 sum += add * 0; sumsq += add * 0*0; total = c + add; # 合并原有数据和补充的0并排序 for(i=0;i<add;i++) { a[c+i] = 0; } n = asort(a); # 计算中位数 if(n % 2 == 1) { median = a[int(n/2)]; } else { median = (a[n/2] + a[n/2 - 1])/2; } # 计算平均值和标准差 ave = sum / total; sd = sqrt(sumsq/total - (sum/total)**2); # 输出结果 OFS="\t"; print ave, sd, median, a[0], a[n-1]; }' "$file" >> "$output"
该方案优势:
- 仅扫描文件一次,避免多次IO操作,大文件处理速度更快
- 无需临时文件,逻辑紧凑
- 减少管道调用开销,性能更优
内容的提问来源于stack exchange,提问作者user236152
相关产品推荐
相关产品推荐

