例如下面是多个基因的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]
为假,这一行的内容不会输出。
这样就保证了输出中每个基因只有第一条记录被输出。