awk使用技巧(1)——提取每个基因比对结果第一行

例如下面是多个基因的blastp比对结果,我们想要提取每个基因的第一行作为最佳比对。

OsCKX2  Ero.03A003270.t1        59.685  635     167     12      2       565     3       619     0.0     666
OsCKX2  Ero.10A027200.t1        64.599  548     164     9       28      564     15      543     0.0     644
OsCKX2  Ero.03A003920.t1        53.235  541     207     12      25      561     30      528     1.16e-174       504
OsCKX2  Ero.04A009290.t1        50.266  563     239     13      5       564     3       527     3.38e-173       501
OsCKX2  Ero.10A016640.t1        51.515  528     224     9       37      562     63      560     3.37e-172       499
OsCKX2  Ero.04A009280.t1        53.348  463     183     10      76      535     3       435     2.41e-152       444
OsCKX2  Ero.03A029100.t1        51.248  521     211     13      51      563     46      531     4.38e-151       444
OsCKX2  Ero.03A039030.t1        47.541  488     212     12      79      560     64      513     1.10e-137       409
OsCKX2  Ero.09A011640.t1        43.889  540     248     15      29      560     21      513     1.83e-132       396
MOC1    Ero.10A018010.t1        79.753  405     66      4       268     662     81      479     0.0     559
MOC1    Ero.04A008160.t1        63.835  412     107     7       274     662     27      419     1.72e-156       457
MOC1    Ero.05A016560.t1        34.328  469     241     12      220     662     341     768     1.85e-55        202
MOC1    Ero.01A010010.t1        35.659  387     194     12      297     662     210     562     5.79e-50        183
MOC1    Ero.02A033090.t2        33.753  397     214     13      282     662     80      443     6.32e-44        164
MOC1    Ero.08A003880.t1        33.504  391     217     10      282     663     324     680     1.56e-42        164
MOC1    Ero.05A002410.t1        32.564  390     221     9       282     663     335     690     1.06e-41        161
OsGS2   Ero.06A023690.t1        90.676  429     35      3       2       428     128     553     0.0     788
OsGS2   Ero.01A041460.t1        76.423  369     72      1       57      410     1       369     0.0     596
OsGS2   Ero.01A010640.t1        76.136  352     84      0       60      411     4       355     0.0     585
OsGS2   Ero.04A025840.t1        71.910  356     80      1       57      412     1       336     0.0     551
OsSLR1  Ero.01A011000.t1        84.810  632     80      8       1       624     1       624     0.0     967
OsSLR1  Ero.10A025290.t2        62.814  398     87      7       233     623     262     605     2.04e-159       471
OsSLR1  Ero.03A022040.t1        50.498  402     163     7       233     623     199     575     2.11e-115       357
OsSLR1  Ero.05A016560.t1        42.823  418     177     8       235     622     384     769     2.80e-93        304
OsSLR1  Ero.08A018300.t1        38.695  429     223     12      213     620     51      460     7.67e-80        261
OsSLR1  Ero.03A036400.t1        38.119  404     201     11      239     621     160     535     6.01e-69        233
D10     Ero.03A027120.t1        83.837  563     72      5       1       550     1       557     0.0     962
D10     Ero.02A036480.t1        60.915  481     168     6       84      550     84      558     0.0     601
D10     Ero.07A018790.t1        53.422  453     168     7       66      507     33      453     5.49e-162       484
D10     Ero.05A014690.t1        54.484  446     143     6       108     550     175     563     2.19e-159       475
D10     Ero.08A000480.t1        54.425  452     145     11      81      525     37      434     1.74e-156       463
HTD1    Ero.06A015720.t1        76.677  626     120     7       9       609     1       625     0.0     960
HTD1    Ero.02A004900.t1        25.000  532     270     23      106     609     148     578     9.27e-18        87.0
HTD1    Ero.08A018950.t1        24.150  559     297     27      76      608     142     599     2.79e-12        69.7
HTD1    Ero.10A019370.t1        27.511  229     133     9       65      272     87      303     4.05e-11        65.9
HTD1    Ero.10A005540.t1        23.556  225     132     7       20      213     40      255     3.83e-08        56.2
HTD1    Ero.04A023920.t1        24.382  566     302     24      68      606     159     625     1.69e-07        54.3
HTD1    Ero.03A027120.t1        26.638  229     136     14      384     606     366     568     2.46e-06        50.4
OsGSr   Ero.01A041460.t1        87.366  372     32      1       1       357     1       372     0.0     677
OsGSr   Ero.01A010640.t1        82.913  357     61      0       1       357     1       357     0.0     645
OsGSr   Ero.04A025840.t1        80.845  355     48      1       1       355     1       335     0.0     607
OsGSr   Ero.06A023690.t1        77.841  352     78      0       4       355     185     536     0.0     600

可以使用awk实现这一目的:

awk 'BEGIN {FS="\t"} !seen[$1]++ {print $0}' tiller.blastout

代码详解

  • seen[$1]:这是一个关联数组,用于记录已经出现过的基因名。
  • !seen[$1]++:这个表达式会首先检查当前基因名是否已经在数组 seen 中存在。!seen[$1] 如果这个基因名是第一次出现,seen[$1] 将会是0,取反后为1,表示条件满足。如果这个基因名已经在数组中出现过,则!seen[$1]会是1取反变为0,表示条件不满足。
  • 如果条件满足(即这个基因名是第一次出现),则!seen[$1]为真,!seen[$1]++会执行,会将当前基因名加入到 seen 数组中,并输出当前行的内容({print $0})。
  • 如果条件不满足(即这个基因名已经出现过),则!seen[$1]为假,这一行的内容不会输出。

这样就保证了输出中每个基因只有第一条记录被输出。