如何用AWK将不同gsub结果输出到对应列以优化VCF处理代码
优化VCF基因型统计的AWK代码:减少子进程+修复列错位
背景
需要给VCF文件新增三列统计信息:
nHomAlt:纯合突变基因型(1/1、1|1)的数量nHet:杂合基因型(0/1、1/0、0|1、1|0)的数量nHomRef:纯合参考基因型(0/0、0|0)的数量
原实现用了多个bcftools子进程,冗余且低效,想改成单AWK进程完成统计。
踩坑的错误写法
最初写了这段代码,结果统计结果完全错位:
BEGIN {print "nHomAlt\tnHet"} {print gsub(/1\|1|1\/1/, "")} {print gsub(/0\|1|1\|0|0\/1|1\/0/, "")}
问题根源:每个print语句都会单独输出一行,导致两个统计值分属不同行,无法对应成同一行的列。
正确实现方式
核心思路是将每个gsub的统计结果存入变量,再在同一行输出所有列。同时要注意:gsub会直接修改目标字符串,因此每次统计都必须使用原行的副本,避免前序替换干扰后续匹配。
完整代码示例:
BEGIN { OFS = "\t" print "nHomRef\tnHet\tnHomAlt" # 输出统计列的表头 } { # 复制当前行到临时变量,避免gsub修改原内容影响后续统计 tmp = $0 nHomRef = gsub(/0\|0|0\/0/, "", tmp) tmp = $0 nHet = gsub(/0\|1|1\|0|0\/1|1\/0/, "", tmp) tmp = $0 nHomAlt = gsub(/1\|1|1\/1/, "", tmp) # 输出原VCF行 + 新增统计列;若仅需统计列,可改为 print nHomRef, nHet, nHomAlt print $0, nHomRef, nHet, nHomAlt }
关键说明
gsub()的返回值就是匹配到的次数,恰好是我们需要的统计数量- 每次统计前重置
tmp为原行内容,否则前序替换会修改字符串,导致后续匹配结果不准确 - 设置
OFS = "\t"确保输出用制表符分隔,与VCF文件格式兼容
内容的提问来源于stack exchange,提问作者Gabriel G.
相关产品推荐
相关产品推荐

