通过多列和子串

时间:2017-02-16 22:45:38

标签: unix awk terminal

我想基于三列获得两个表之间的重叠。

档案1

 Chr        B      C       Start  End   F   G   E    D   
chr1    HAVANA  gene    11869   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr1    HAVANA  gene    100000  112000  .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr3    HAVANA  gene    11870   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr3    HAVANA  gene    11839   11869   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr2    HAVANA  gene    11869   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";

...

文件2

 A                       B           Start  End    Chr          D  
ENSG00000177697     ENST00000525333 832986  833026  11          1
ENSG00000197283     ENST00000876382 100000  112000  1           1
ENSG00000194582     ENST00000184632 11869   14409   2           1
ENSG00000174528     ENST00000241053 154728  184728  12          1
ENSG00000103629     ENST00000816493 832986  917483  13          1 
ENSG00000183628     ENST00000816472 711633  782163  11          1
ENSG00000192748     ENST00000164924 832986  982732  CHK_1231    1
ENSG00000183643     ENST00000917473 183728  194873  3           1
ENSG00000183647     ENST00000184637 800000  819483  2           1
ENSG00000177697     ENST00000184627 100023  120000  11          1

期望的输出:

Chr        B      C       Start  End   F   G   E    D   
chr1    HAVANA  gene    100000  112000  .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr2    HAVANA  gene    11869   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";

问题是第5列中文件2中的数字是第一个文件的第1列的子字符串(因此,而不是11,它会说chr11)。表2的第4和第5列应等于文件1(开始和结束)中的第4列和第5列。我希望输出完全看起来像文件1,只是元素应该等于文件2中的元素。

我不熟悉awk语法,对我来说这并不直观,但我在扫描之前的帖子时发现这行,我想可以扩展这个命令:

awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1 > file1_subset2

1 个答案:

答案 0 :(得分:0)

@ELHL:试试:

awk 'FNR==NR{sub(/[[:alpha:]]+/,"",$1);A[$1,$4,$5]=$0;next} {sub(/[[:alpha:]]+/,"",$(NF-1));} ((($NF-1),$3,$4) in A){print A[($NF-1),$3,$4]}'   SUBSEP=,   Input_file1  Input_file2

如果两者都根据您的要求匹配,它将打印file1的值,请尝试告诉我。

现在也添加非单线形式的解决方案。

awk 'FNR==NR{
                sub(/[[:alpha:]]+/,"",$1);
                A[$1,$4,$5]=$0;
                next
            }
            {
                sub(/[[:alpha:]]+/,"",$(NF-1));
            }
     ((($NF-1),$3,$4) in A){
                                print A[($NF-1),$3,$4]
                           }
    '  SUBSEP=,    Input_file1  Input_file2

EDIT2:添加一个函数,我可以删除2次写入的sub,它实际上在不同的字段中执行相同的操作。

awk 'function remove_chars(a){sub(/[[:alpha:]]+/,"",$a)} FNR==NR{remove_chars($1);A[$1,$4,$5]=$0;next} {remove_chars($(NF-1));} ((($NF-1),$3,$4) in A){print A[($NF-1),$3,$4]}'  SUBSEP=, Input_file1   Input_file2

非单一衬里形式的解决方案也如下。

awk 'function remove_chars(a){
                                sub(/[[:alpha:]]+/,"",$a)
                             }
     FNR==NR                 {
                                remove_chars($1);
                                A[$1,$4,$5]=$0;
                                next
                             }
                             {
                                remove_chars($(NF-1));
                             }
     ((($NF-1),$3,$4) in A)  {
                                print A[($NF-1),$3,$4]
                             }
   ' SUBSEP=,   Input_file1   Input_file2