如何使用 awk 获取所需的输出并将输出添加到另一个文件中?

如何使用 awk 获取所需的输出并将输出添加到另一个文件中?

我的test.gtf文件如下所示:

测试.gtf

chr2      Cufflinks       exon    5072    5353    .       -       .       transcript_id "transc_00000019"; gene_id "XLOC_000017"; gene_name "XLOC_000017"; exon_number "1"; inf "unknown"; Other "XLOC_000017";
chr2      Cufflinks       transcript      5072    5353    .       -       .       transcript_id "transc_00000019"; gene_id "XLOC_000017"; gene_name "XLOC_000017"; oId "TCONS_00000019"; class_code "u"; tss_id "TSS19"; inf "unknown"; original_gene_id "XLOC_000017";
chr2      Cufflinks       exon    20450   20769   .       +       .       transcript_id "transc_00000001"; gene_id "XLOC_000001"; gene_name "XLOC_000001"; exon_number "1"; inf "unknown"; original_gene_id "XLOC_000001";
chr2      Cufflinks       transcript      20450   20769   .       +       .       transcript_id "transc_00000001"; gene_id "XLOC_000001"; gene_name "XLOC_000001"; oId "TCONS_00000001"; class_code "u"; tss_id "TSS1"; inf "unknown"; original_gene_id "XLOC_000001";
chr2      Cufflinks       exon    24985   25273   .       +       .       transcript_id "transc_00000002"; gene_id "XLOC_000002"; gene_name "XLOC_000002"; exon_number "1"; inf "unknown"; original_gene_id "XLOC_000002";
chr2      Cufflinks       transcript      24985   25273   .       +       .       transcript_id "transc_00000002"; gene_id "XLOC_000002"; gene_name "XLOC_000002"; oId "TCONS_00000002"; class_code "u"; tss_id "TSS2"; inf "unknown"; original_gene_id "XLOC_000002";
chr2      Cufflinks       exon    43499   43705   .       +       .       transcript_id "transc_00000003"; gene_id "XLOC_000003"; gene_name "XLOC_000003"; exon_number "1"; inf "unknown"; original_gene_id "XLOC_000003";
chr2      Cufflinks       transcript      43499   43705   .       +       .       transcript_id "transc_00000003"; gene_id "XLOC_000003"; gene_name "XLOC_000003"; oId "TCONS_00000003"; class_code "u"; tss_id "TSS3"; inf "unknown"; original_gene_id "XLOC_000003";

我尝试transcript在第三列中使用以下命令,并尝试使用第五列和第四列获取数字,如下所示:

awk -F"\t" '$3=="transcript" {ID=substr($9, length($9)-16, 15); L[ID]+=$5-$4+1}
           END{for(i in L){print i"\t"L[i]}}' test.gtf

但上面的命令没有给出输出。输出应如下所示:

transcript_id   num
transc_00000019 282 
transc_00000001 320
transc_00000002 289
transc_00000003 207

我还有另一个文件,test2.tsv如下所示:

gene_id           transcript_id      column3       column4     column5  column6
XLOC_000017      transc_00000019         -             -          -         - 
XLOC_000001      transc_00000001         -             -          -         - 
XLOC_000002      transc_00000002         -             -          -         - 
XLOC_000003      transc_00000003         -             -          -         - 

我得到的输出应该添加为test2.tsv文件中的另一列,它应该如下所示:

测试2.tsv

gene_id           transcript_id      column3       column4     column5  column6     num
XLOC_000017      transc_00000019         -             -          -         -        282
XLOC_000001      transc_00000001         -             -          -         -        320
XLOC_000002      transc_00000002         -             -          -         -        289
XLOC_000003      transc_00000003         -             -          -         -        207

答案1

使用awk,如果分隔符是空格或更多,那么你可以尝试;

$ awk -F' +|"' 'NR==FNR {a[$11]=$5-$4+1;next} FNR==1{$(NF+1)="num"}{print $0,a[$2]}' test.gtf test2.tsv | column -t

不过,如果确实是选项卡,那么你可以尝试;

awk -F'\t|"' 'NR==FNR {a[$11]=$5-$4+1;next} FNR==1{$(NF+1)="num"}{print $0,a[$2]}' test.gtf test2.tsv | column -t

输出

gene_id      transcript_id    column3  column4  column5  column6  num
XLOC_000017  transc_00000019  -        -        -        -        282
XLOC_000001  transc_00000001  -        -        -        -        320
XLOC_000002  transc_00000002  -        -        -        -        289
XLOC_000003  transc_00000003  -        -        -        -        207

答案2

输入中字段之间的空格不是制表符,因此不要告诉 awk 它们是带有 的制表符-F"\t",只需删除该语句并更改ID=substr($9, length($9)-16, 15)ID=substr($0, length($0)-16, 15)(或者如果您愿意,可以使用 $NF 而不是 $0):

$ awk '$3=="transcript" {ID=substr($0, length($0)-16, 15); L[ID]+=$5-$4+1}
           END{for(i in L){print i"\t"L[i]}}' test.gtf
id "XLOC_000017 282
id "XLOC_000001 320
id "XLOC_000002 289
id "XLOC_000003 207

看起来您在通话中使用的号码substr()已关闭,并且您缺少 prepending transc_,我希望您可以解决这个问题。

无论您输入的空格是什么,上述内容都将起作用。

顺便说一句,不要使用全部大写的变量名,这样它们就不会与内置变量名冲突,并且永远不要使用字母l作为变量名,因为它看起来太像数字了1。另外,使用 OFS 指定分隔输出字段的内容:

$ awk -v OFS='\t' '$3=="transcript" {id=substr($0, length($0)-16, 15); num[id]+=$5-$4+1}
           END{for(id in num){print id, num[id]}}' test.gtf
id "XLOC_000017 282
id "XLOC_000001 320
id "XLOC_000002 289
id "XLOC_000003 207

相关内容