我有两组基因组坐标。问题是file1的范围很小,当我与file2比较时,它可以有多个重叠。所以我想选一个尽可能接近的。问题是file1的第一行(假设您有许多行)可以包含file2的第一行和第二行。如何在循环中使用此条件($1==col2[$1])&&(在2美元= col2[2]美元),,($3<=col2[$3])所以我只能取file2的第二行
file_2
1 1400158 1400608 + ENSE00003459370
1 1400158 1400544 + ENSE00003542737
1 2515258 2515401 - ENSE00001912971
1 11025110 11025203 + ENSE00003713710
1 13892792 13893756 + ENSE00003793480
1 15328277 15328429 + ENSE00003788031
1 15329346 15329541 + ENSE00003484579
1 15247280 15247395 + ENSE00002149103
我有file1
1 1400473 1400544 +
期望输出
1 1400158 1400544 + ENSE00003542737
我试过了
awk 'NR==FNR { id[$1]=$1; id1[$2]=$2; id2[$3]=$3; next } ($1 == id && $2 >= id1 && $3 <= id2) { print $0"t"id[$1]"t"id1[$2]"t"id2[$3]}' file1.txt file2.txt
但是我没有得到输出。我不知道我做错了什么
这里有很多缺失的信息/混乱,例如,每个文件的行大小可能很重要,而且您明确要求的内容不太可能是您实际需要的,因为它没有包含任何对file1的引用,这表明为什么保留file2的结果。
但是猜测一些可能接近你要找的东西…
#! /usr/bin/awk -f
NR==FNR && !/^$/{ # collect all file1 (no ens_id)
n = NR;
ch[n] = $1;
lo[n] = $2;
hi[n] = $3;
# sense[n] = $4; # could check direction as well
}
NR!=FNR && !/^$/ { # each item file2
i=last_hit;
while(i++ < n){ # each item in file1
# *** assume lo strictly before hi
if(($1 != ch[i]) || ($2 > hi[i]) || ($3<lo[i]) ){ # no chance
last_hit = i-1; # retry with next
next
}
else { # plausible
if( ($2<=lo[i]) && ($3>=hi[i]) ){ # contained?
print; # hit
last_hit = i-1; # in case dup hits
}
}
}
}
有很多错误,但基本上你想知道;
如果你有一个区间(file1)包含在一个来自file2的命名区间中,大概是因为你想知道来自file1的区间的引用名称。
重要的部分不在于找到匹配时选择打印什么,
您可以修复
,而在于如何在考虑第二个文件中的每一行时反复遍历第一个文件。
last_hit
是一个(不成熟的)优化,它取决于在文件中排序的间隔,它应该允许更少的file1在您执行file2时被重新访问。