让我用一个虚拟的例子来解释我的问题。 这是文件A -
1 10 20 aa
2 30 40 bb
3 60 70 cc
. .. .. ..
,这是文件B -
10 15 xx yy mm
21 29 mm nn ss
11 18 rr tt yy
69 90 qq ww ee
.. .. .. .. ..
我正在尝试合并这些文件A和B,以便在A的行和B的行之间存在一些重叠。
在A的行和B的行之间重叠,在我的情况下: 对于A的行,范围从2美元到3美元之间有一些共同点,B行的范围从1美元到2美元不等。在上面的例子中,范围(10,20)和范围(10,15)之间存在重叠。 这里范围(10,20)= [10,11,12,13,14,15,16,17,18,19]和 范围(10,15)= [10,11,12,13,14]
所以预期的输出是 -
1 10 20 aa 10 15 xx
1 10 20 aa 11 18 rr
3 60 70 cc 69 90 qq
我试过这种方式(使用和awk):
for peak in State.peaks:
i = peak[-1]
peak = peak[:-1]
a = peak[1]
b = peak[2]
d = State.delta
c = ''' awk '{id=%d;delta=%d;a=%d;b=%d;x=%s;y=%s;if((x<=a&&y>a)||(x<=b&&y>b) || (x>a&&y<=b)) print id" "$7" "$3-$2} ' %s > %s ''' % (i, d, a, b, "$2-d", "$3+d", State.fourD, "file"+str(name))
os.system(c)
想要完全删除python部分,因为这需要很长时间。
答案 0 :(得分:0)
awk
救援!
$ awk 'function intersect(x1,y1,x2,y2)
{return (x1>=x2 && x1<y2) || (x2>=x1 && x2<y1)}
NR==FNR{lower[$0]=$2; upper[$0]=$3; next}
{for(k in lower)
if(intersect(lower[k],upper[k],$1,$2))
print k,$1,$2,$3}' file1 file2
请注意
(x1>=x2 && x1<y2) || (x2>=x1 && x2<y1)
= [x1>=x2 || (x2>=x1 && x2<y1)] && [x1<y2 || (x2>=x1 && x2<y1)]
= [(x1>=x2 || x2>=x1) && (x1>=x2 || x2<y1) && [// symmetric 1~2]
= [True && x2 < max(x1,y1)] && [// symmetric 1~2]
= x2<y1 && y2<x1
这相当于@Jonathan Leffler的条件,它更紧凑,更有效率,即使一开始并不是微不足道。
答案 1 :(得分:0)
这个Awk脚本完成了这项工作:
NR == FNR { record[NR] = $0; lo[NR] = $2; hi[NR] = $3; nrecs = NR; next }
NR != FNR { # Overlap: lo[A] < hi[B] && lo[B] < hi[A]
for (i = 1; i <= nrecs; i++)
{
if (lo[i] < $2 && $1 < hi[i])
print record[i], $1, $2, $3
}
}
我将其保存为range-merge-53.awk
(53
只是一个随机的两位数素数)。我从您的示例数据中创建了file.A
和file.B
,然后运行:
$ awk -f range-merge-53.awk file.A file.B
1 10 20 aa 10 15 xx
1 10 20 aa 11 18 rr
3 60 70 cc 69 90 qq
$
关键是'重叠'条件,它必须排除每个范围的高值 - 通常用[lo..hi)
表示开放闭合范围。
可以省略next
或NR != FNR
条件(但不是两者),代码也可以正常工作。
另见Determine whether two date ranges overlap - 范围的逻辑适用于日期和整数以及浮点等。