If statement 按多列查找

If statement 按多列查找,if-statement,awk,If Statement,Awk,一般问题: 我正在尝试使用索引根据引用表查找名称。文档和引用表中第一列的值需要匹配,但是我想检查文件中的数值是否位于引用表中的两个数值列之间。如果是这样,我想将引用表中相应的名称打印到文件中的新列中。否则,我想打印NA 具体例子 我想匹配文件的第一列Chr和引用表,看看它们是否匹配。如果是这样,我想看看文件pos的第2列中的值是否大于引用开始的第3列,但小于引用结束的第4列。如果是这样,我想将引用表中相应的col 4 Gene_名称添加到文件的新第4列。如果没有相应的基因,我想把NA放在我的文件

一般问题: 我正在尝试使用索引根据引用表查找名称。文档和引用表中第一列的值需要匹配,但是我想检查文件中的数值是否位于引用表中的两个数值列之间。如果是这样,我想将引用表中相应的名称打印到文件中的新列中。否则,我想打印NA

具体例子 我想匹配文件的第一列Chr和引用表,看看它们是否匹配。如果是这样,我想看看文件pos的第2列中的值是否大于引用开始的第3列,但小于引用结束的第4列。如果是这样,我想将引用表中相应的col 4 Gene_名称添加到文件的新第4列。如果没有相应的基因,我想把NA放在我的文件的genename列中

文件

参考文献

Chr Start    End        Gene_name
2L  1884260  1888828    FBgn0262029
2L  19531851 19547482   FBgn0052532
2L  2350523  2361570    FBgn0023536
2L  4647871  4648646    FBgn0029718
期望输出

Chr pos     p-val      Gene_name
2L  1885826 2.638e-08  FBgn0262029
2L  1996567 5.12e-05   NA
2L  2360597 9.472e-05  FBgn0023536
2R  2360621 9.472e-05  NA
2R  2360623 9.472e-05  NA
企图

我一直在尝试调整这个问题的代码来实现这一点。

到目前为止,我有:

awk -F"\t" '                                       #Set Field separator to     "\t"
FNR==NR {a[$1];a[$2];a[$3];next}                    #Read data from Reference using field #1, field #2, field #3 as index in to array a
{if ($1 in a)                               #Test if field #1 in Table is found in a
{if ($2 > a[$2])
{if ($2 < a[$3])
print $0, a[$4]                       #If found, print line of f1.txt with sum and index from array
else print $0,"NA"     #If not found print line of f1.txt with NotFound
}
else print $0,"NA"     #If not found print line of f1.txt with NotFound
}
else print $0,"NA"     #If not found print line of f1.txt with NotFound
}
' OFS="\t" Referance.txt  File.txt                       #Set Output field separator to , and read files
我认为我在嵌套的if-else语句中的某个地方犯了错误,但我不确定我做错了什么。如果您有任何建议,我们将不胜感激

快来营救

awk      '{k=$1} 
  NR==FNR {c[k]++; start[k,c[k]]=$2; end[k,c[k]]=$3; gene[k,c[k]]=$4; next} 
          {$(NF+1)=FNR==1?"Gene_name":"NA"} 
  k in c  {for(i=1;i<=c[k];i++) 
              if(start[k,i]<=$2 && $2<=end[k,i]) 
                  {$NF=gene[k,i]; 
                   break}}1' file2 file1 | column -t


Chr  pos      p-val      Gene_name
2L   1885826  2.638e-08  FBgn0262029
2L   1996567  5.12e-05   NA
2L   2360597  9.472e-05  FBgn0023536
2R   2360621  9.472e-05  NA
2R   2360623  9.472e-05  NA
备注:假设第二个文件适合内存,并且范围不重叠,如果是,则只报告第一个匹配。进行线性扫描,因此如果其中一个文件较大,则速度可能较慢,更好的算法可能从排序范围开始,同时也将验证它们是否重叠

代码应该易于阅读,基本上是将完整的file2加载到多个数组中,并检查第一个文件的条目是否匹配范围

2L  1885826 2.638e-08   NA
2L  1996567 5.12e-05    NA
2L  2360597 9.472e-05   NA
2R  2360621 9.472e-05   NA
2R  2360623 9.472e-05   NA
awk      '{k=$1} 
  NR==FNR {c[k]++; start[k,c[k]]=$2; end[k,c[k]]=$3; gene[k,c[k]]=$4; next} 
          {$(NF+1)=FNR==1?"Gene_name":"NA"} 
  k in c  {for(i=1;i<=c[k];i++) 
              if(start[k,i]<=$2 && $2<=end[k,i]) 
                  {$NF=gene[k,i]; 
                   break}}1' file2 file1 | column -t


Chr  pos      p-val      Gene_name
2L   1885826  2.638e-08  FBgn0262029
2L   1996567  5.12e-05   NA
2L   2360597  9.472e-05  FBgn0023536
2R   2360621  9.472e-05  NA
2R   2360623  9.472e-05  NA