AWK脚本优化:在均值结果旁输出文件名(避免每行重复输出)
问题分析与修正方案
你的问题出在把{print FILENAME}放在了AWK的主处理块——这个块会对每一行输入执行一次,所以处理6000万行就会输出6000万次文件名。正确的做法是把文件名输出逻辑放到END块里,因为END块只会在整个文件处理完成后执行一次。
修正后的脚本
首先注意:如果你的输入文件包含表头(比如示例里的第一行Locus Total_Depth...),计算均值时要排除表头行,否则会把表头字符串当成0计入,导致结果错误。以下是完整修正脚本:
allsamples="R3 SM261_T SM382_T R6" # 只打印一次表头到总结果文件 echo -e "ID\tCoverage" > All_samples_coverage.txt for sample in $allsamples do # AWK仅做累加,在END块一次性输出文件名和均值 awk '{sum+=$2} END {print FILENAME, "Average = ", sum/(NR-1)}' "$sample.dep" >> All_samples_coverage.txt done
如果你的输入文件没有表头,直接用sum/NR代替sum/(NR-1)即可。
为什么原来的写法错误?
AWK的执行逻辑是:
- 先执行
BEGIN块(仅一次) - 对每一行输入,执行匹配的主处理块(无pattern则默认匹配所有行)
- 所有行处理完后,执行
END块(仅一次)
你之前的写法把{print FILENAME}放在主处理块,相当于每读一行就输出一次文件名,这才导致了重复输出的问题。
保留临时文件的版本
如果需要保留单个样本的临时结果文件,可以改成:
allsamples="R3 SM261_T SM382_T R6" echo -e "ID\tCoverage" > All_samples_coverage.txt for sample in $allsamples do awk '{sum+=$2} END {print FILENAME, "Average = ", sum/(NR-1)}' "$sample.dep" > "$sample.mean_coverage.temp" cat "$sample.mean_coverage.temp" >> All_samples_coverage.txt done
内容的提问来源于stack exchange,提问作者Gf.Ena
相关产品推荐
相关产品推荐

