Linux

使用 AWK 搜尋和替換,但在具有多列和分隔符的文件中

  • September 16, 2021

我想用文件 2 中的基因註釋資訊替換文件 1 中的基因名稱。

文件 1 如下所示:第一列中的 OG 標識符和第二到 Xnd 列中的基因名稱):

OG0000008,aly11306X1, aly15270X1, aly1603X45, aly1603X46
OG0000009,Tni22G01870, Tni22G01880, Tni22G01890, Tni22G01900, Tni22G01910, Tni22G01920
OG0000010,BANYX1.2.t00767, BANYX1.2.t00769, BANYX1.2.t00774, BANYX1.2.t00775, BANYX1.2.t00861

第 2 列到第 X 列的所有基因名稱都需要替換為文件 2 中的註釋資訊,如下所示: 第一列中的基因標識符(可以出現多次!),然後是第 2 到第 5 列中的多個註釋:

   aly11306X1  Pfam    PF16207 IPR032443   
   aly15270X1  Pfam    PF13923
   aly1603X45  Pfam    PF01509 IPR002501   GO:0006396
   aly1603X46  Pfam    PF04845 IPR006628   GO:0000977|GO:0032422
   Tni22G01870 Pfam    PF02779 IPR005475   
   Tni22G01880 Pfam    PF02780 IPR033248   
   Tni22G01890 Pfam    PF00456 IPR005474   
   Tni22G01900 Pfam    PF04949 IPR007033   
   Tni22G01910 Pfam    PF00250 IPR001766   GO:0003700|GO:0006355|GO:0043565
   Tni22G01920 Pfam    PF00379 IPR000618   GO:0042302
   BANYX1.2.t00767 Pfam    PF00400 IPR001680   GO:0005515
   BANYX1.2.t00769 Pfam    PF00400 IPR001680   GO:0005515
   BANYX1.2.t00774 Pfam    PF00400 IPR001680   GO:0005515
   BANYX1.2.t00775 Pfam    PF00400 IPR001680   GO:0005515
   BANYX1.2.t00861 Pfam    PF04949 IPR007033   
   BANYX1.2.t00861 Pfam    PF08704 IPR014816   GO:0016429|GO:0030488|GO:0031515

在輸出文件中,我想從文件 1 中檢索第 1 列中的 OG 標識符,然後從文件 2 中檢索第 3 列的基因註釋。換句話說,文件 1 中的基因名稱應替換為文件 2 的基因 PF 編號.我並不真正關心這裡的分隔符。

輸出:

OG0000008   PF16207 PF13923 PF01509 PF04845
OG0000009   PF02779 PF02780 PF00456 PF04949 PF00250 PF00379
OG0000010   PF00400 PF04949 PF08704

我試圖用 grep 解決這個問題,但實際上這些文件有 1000 多條記錄,所以沒有用。我決定去 AWK,但不幸的是我的 awk 知識有限,但我真的想變得更好。你能在這裡幫助我嗎?

我試圖從簡單的開始,只在第二列中搜尋,但它會列印整個文件:

awk -F "," 'NR==FNR{a[$2];next} $2 in a {print $1, $3}' File1 File2

有人可以幫我嗎?

對數組數組使用 GNU awk:

$ cat tst.awk
NR==FNR {
   genes_annots[$1][$3]
   next
}
{
   delete annots
   for ( i=2; i<=NF; i++ ) {
       gene = $i
       if ( gene in genes_annots ) {
           for ( annot in genes_annots[gene] ) {
               annots[annot]
           }
       }
   }
   printf "%s", $1
   for (annot in annots) {
       printf "%s%s", OFS, annot
   }
   print ""
}
$ awk -f tst.awk file2 FS='[, ]+' file1
OG0000008 PF01509 PF16207 PF13923 PF04845
OG0000009 PF00250 PF02779 PF00379 PF04949 PF00456 PF02780
OG0000010 PF08704 PF04949 PF00400

如果您有 2 個具有相同註釋的獨立基因,上述方法甚至可以工作,例如基因 Tni22G01900 和 BANYX1.2.t00861 都具有註釋 PF04949:

$ cat file3
OG0000099,Tni22G01900, BANYX1.2.t00861

$ awk -f tst.awk file2 FS='[, ]+' file3
OG0000099 PF08704 PF04949

我在上面假設註釋出現在每行輸出中的順序並不重要,只要它們都存在並且在該行中是唯一的。

引用自:https://unix.stackexchange.com/questions/669270