awk使用另一个范围更新文件中的未知值

时间:2016-11-18 15:50:01

标签: awk

我正在尝试修改@karakfa友情提供的awk,以更新unknown$6的所有file2值,如果$4file2$1的{​​{1}}范围内file1。如果$6以外的unknown中已有值,则会跳过该值并处理下一行。在我的awk尝试中,最终输出为6 tab-delimited fields。目前awk已运行但unknown值未更新,我似乎无法解决此问题。谢谢:))

file1 (以空格分隔)

chr1:4714792-4852594 AJAP1
chr1:4714792-4837854 AJAP1
chr1:9160364-9189229 GPR157
chr1:9160364-9189229 GPR157
chr1:15783223-15798586 CELA2A
chr1:15783224-15798586 CELA2A

file2 (制表符分隔)

chr1    3649533    3649653    chr1:3649533-3649653    .    TP73
chr1    4736396    4736516    chr1:4736396-4736516    .    unknown   
chr1    5923314    5923434    chr1:5923314-5923434    .    NPHP4
chr1    9161991    9162111    chr1:9161991-9162111    .    unknown
chr1    9162050    9162051    chr1:9162050-9162051    .    rs6697376

期望的输出 ---第二个和第四个未知值根据$1 file1

的范围进行更新
chr1    3649533    3649653    chr1:3649533-3649653    .    TP73
chr1    4736396    4736516    chr1:4736396-4736516    .    AJAP1  
chr1    5923314    5923434    chr1:5923314-5923434    .    NPHP4
chr1    9161991    9162111    chr1:9161991-9162111    .    unknown
chr1    9162050    9162051    chr1:9162050-9162051    .    rs6697376

awk的当前输出

awk -v OFS='\t' 'NR==FNR{
                       rstart[a[1]]=a[2]
                       rend[a[1]]=a[3]
                       value[a[1]]=$2
                       next} 
 $6~/unknown/ && $2>=rstart[$1] && $3<=rend[$1] {sub(/unknown/,value[$1],$6)}1' hg19.txt input |    column -t
chr1  3649533  3649653  chr1:3649533-3649653  .  TP73
chr1  4736396  4736516  chr1:4736396-4736516  .  unknown
chr1  5923314  5923434  chr1:5923314-5923434  .  NPHP4
chr1  9161991  9162111  chr1:9161991-9162111  .  unknown
chr1  9162050  9162051  chr1:9162050-9162051  .  rs6697376

编辑:

awk -v OFS='\t' 'NR==FNR{split($1,a,/[:-]/)
                       rstart[a[1]]=a[2]
                       rend[a[1]]=a[3]
                       value[a[1]]=$2
                       next} 
 $6~/unknown/ && $2>=rstart[$1] && $3<=rend[$1] {sub(/unknown/,value[$1],$6)}1' hg19.txt input |    column -t

问题2的可能解决方案:

----- $2中匹配的file1值与作为开头的第一行rstart[a[1]]=a[2]和作为结尾的最后一行rend[a[1]]=a[3]相结合

chr1:4714792-4837854 AJAP1
chr1:9160364-9189229 GPR157
chr1:15783223-15798586 CELA2A

1 个答案:

答案 0 :(得分:1)

这是另一个脚本(由于线性扫描而不是更有效的搜索方法,效率很低)但工作起来更简单。

$ awk -v OFS='\t' 'NR==FNR{split($1,a,"[:-]"); k=a[1]; c[k]++;
                           rstart[k,c[k]]=a[2];
                           rend[k,c[k]]=a[3];
                           value[k,c[k]]=$2;
                           next} 
        $6=="unknown" && ($1 in c) {k=$1; 
                             for(i=1; i<=c[k]; i++) 
                                if($2>=rstart[k,i] && $3<=rend[k,i]) 
                                   {$6=value[k,i]; break}}1' file1 file2 |
 column -t

因为可以有多个匹配,所以这个匹配使用第一个匹配。

chr1  3649533  3649653  chr1:3649533-3649653  .  TP73
chr1  4736396  4736516  chr1:4736396-4736516  .  AJAP1
chr1  5923314  5923434  chr1:5923314-5923434  .  NPHP4
chr1  9161991  9162111  chr1:9161991-9162111  .  GPR157
chr1  9162050  9162051  chr1:9162050-9162051  .  rs6697376

请注意,第四条记录也会根据规则进行匹配。