AWK使用vcf(文本)文件

时间:2013-10-18 12:35:28

标签: bash awk header tab-delimited-text

我想创建awk代码,它会修改这样的文本:

  1. 制表符分隔所有列
  2. 删除所有以“## text”
  3. 开头的列
  4. 并保留标题,开头“#header”
  5. 我有这段代码,但不太好:

    #!/bin/bash
    for i
    in *.vcf;
    do
        awk 'BEGIN {print  "CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILT\tINFO\tFORMAT"}' |
        awk '{$1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t" $8 "\t" $9}' $i |
        awk '!/#/' > ${i%.vcf}.tsv;
    done
    

    INPUT:

    > ##fileformat=VCFv4.1
    > ##FORMAT=<ID=GQX,Number=1,Type=Integer,Description="Minimum of {Genotype quality assuming variant position,Genotype quality assuming
    > non-variant position}">
    > #CHROM    POS ID  REF ALT QUAL    FILTER  INFO    FORMAT  1 chr1  10385471    rs17401966  A   G   100.00  PASS    DP=67;TI=NM_015074;GI=KIF1B;FC=Silent   GT:GQ:AD:VF:NL:SB:GQX   0/1:100:29,38:0.5672:20:-100.0000:100
    > chr1  17380497    rs2746462   G   T   100.00  PASS    DP=107;TI=NM_003000;GI=SDHB;FC=Synonymous_A6A;EXON  GT:GQ:AD:VF:NL:SB:GQX   1/1:100:0,107:1.0000:20:-100.0000:100
    > chr1  222045446   rs6691170   G   T   100.00  PASS    DP=99   GT:GQ:AD:VF:NL:SB:GQX   0/1:100:49,50:0.5051:20:-100.0000:100
    

    输出:我想要什么

    > CHROM POS   ID          REF  ALT  QUAL    FILTER  INFO             etc...
    > hr1   10385471  rs17401966  A   
    > G 100.00  PASS    DP=67;TI=NM_015074;GI=KIF1B;
    

1 个答案:

答案 0 :(得分:5)

您希望将整个程序放在一个awk调用中:

for f in *.vcf; do
    awk '
        BEGIN {OFS = "\t"}
        /^##/ {next}
        /^#/ {sub(/^#/,"",$1)}
        {$1=$1; print}
    ' "$f" > "${f/%vcf/tsv}"
done

此程序将跳过任何以##开头的记录,将删除包含它的行的前导哈希,然后使用tab作为字段分隔符打印每一行。

awk程序是一系列condition {action}对。对于输入中的每个记录,如果条件为真,则执行操作块,否则忽略它。如果省略该条件,则无条件地执行操作块。

此示例中的一个棘手问题是$1=$1 - 当字段被修改时,awk将重新构建记录,使用输出字段分隔符(OFS变量)连接字段。