首页 > 解决方案 > 如何遍历awk中的列

问题描述

我有一个简短的脚本可以执行我想要的操作,但是我想将该脚本应用于文件中的每一列(无论我有多少列)

输入文件(制表符分隔):

1/2:17,6:23:85:85,0,370 0/0:51,6:57:17:0,17,1359    0/0:3,0:3:9:0,9,99
0/0:3,0:3:0:.:.:0,0,38  0/0:1,0:1:3:.:.:0,3,33  0/1:1,2:3:26:0|1:13813_T_G:81,0,26
./.:2,0:2:.:.:.:0,0,0   0/0:1,0:1:3:.:.:0,3,33  0/1:1,2:3:26:0|1:13813_T_G:81,0,26
./.:0,0:0:.:0,0,0   1/1:0,4:4:12:131,12,0   ./.:0,0:0:.:0,0,0
1/1:0,2:2:6:1|1:14590_G_A:90,6,0    0/0:3,0:3:9:.:.:0,9,98  0/0:1,0:1:3:.:.:0,3,30

假如说:

0/1、0/2、1/2 = HET

0/0 = ?REF

1/1, 2/2 = HOM

其他 = 未知

所需的输出(基于每列的前三个字符):

1/2:17,6:23:85:85,0,370 0/0:51,6:57:17:0,17,1359    0/0:3,0:3:9:0,9,99  HET ?REF    ?REF
0/0:3,0:3:0:.:.:0,0,38  0/0:1,0:1:3:.:.:0,3,33  0/1:1,2:3:26:0|1:13813_T_G:81,0,26  ?REF    ?REF    HET
./.:2,0:2:.:.:.:0,0,0   0/0:1,0:1:3:.:.:0,3,33  0/1:1,2:3:26:0|1:13813_T_G:81,0,26  unknown ?REF    HET
./.:0,0:0:.:0,0,0   1/1:0,4:4:12:131,12,0   ./.:0,0:0:.:0,0,0   unknown HOM unknown
1/1:0,2:2:6:1|1:14590_G_A:90,6,0    0/0:3,0:3:9:.:.:0,9,98  0/0:1,0:1:3:.:.:0,3,30  HOM ?REF    ?REF

我编写了一个脚本,它采用第一列并吐出正确的 HET/?REF/HOM/unknown:

awk 'BEGIN{FS=OFS="\t"}{if(($1 ~ /0\/1/) || ($1 ~ /1\/2/) || ($1 ~ /0\/2/)) print $1,"HET"; \
 else if(($1 ~ /1\/1/) || ($1 ~ /2\/2/)) print $1,"HOM"; \
 else if($1 ~ /0\/0/) print $1,"?REF"; \
 else print $1,"unknown";}' inputfile

这给了我以下信息:

1/2:17,6:23:85:85,0,370 HET
0/0:3,0:3:0:.:.:0,0,38  ?REF
./.:2,0:2:.:.:.:0,0,0   unknown
./.:0,0:0:.:0,0,0   unknown
1/1:0,2:2:6:1|1:14590_G_A:90,6,0    HOM

到目前为止,一切都很好。现在,我想使用上面的脚本遍历每一列,然后按如下所示的顺序打印正确的 REF/HET/HOM,即 genotype1 匹配 coded1 和 genotype2 匹配 coded2 等。

genotype1   genotype2   genotype3   coded1  coded2  coded3
1/2:17,6:23:85:85,0,370 0/0:51,6:57:17:0,17,1359    0/0:3,0:3:9:0,9,99  HET ?REF    ?REF

这就是我被卡住的地方,我害怕!我不确定如何遍历每一列...

请放轻松,我是临床医生而不是生物信息学家!乙

标签: awk

解决方案


这里的方法略有不同,可能更容易维护

$ awk 'BEGIN {FS=OFS="\t"
              map["0/1"]=map["1/2"]=map["0/2"]="HET"
              map["1/1"]=map["2/2"]="HOM"
              map["0/0"]="?REF"}

       NR==1 {print; next}  # if you have a header, if not remove
             {printf "%s", $0
              for(i=1;i<=NF;i++) {
                  t=substr($i,1,3);
                  printf "%s", OFS (t in map?map[t]:"unknown")}
              print ""}' file


             

推荐阅读