使用 AWK 搜索并替换,但在具有多个列和分隔符的文件中

使用 AWK 搜索并替换,但在具有多个列和分隔符的文件中

我想用文件 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 至 Xnd 列的所有基因名称都需要替换为文件 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

有人可以帮我吗?

答案1

对数组的数组使用 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

上面我假设注释在每行输出中出现的顺序并不重要,只要它们在该行中都存在且唯一。

相关内容