如何删除数字范围内的重叠(AWK)

时间:2013-05-19 20:06:08

标签: awk overlap genetic-programming

我正在尝试删除文件中的重叠。

  • 有一堆记录以'A'开头,并且有'起始值'和'结束值'。
  • 还有一堆以'B'开头的记录,也有范围,并显示可能与以'A'开头的记录重叠。我们的想法是从A中删除重叠范围,因此只存在非重叠范围。

B中的某些记录具有相同的“起始值”,而其他记录具有与A相同的“结束值”。因此,如果A的范围为0 - 100且B的范围为0 - 32那我的预期输出是: A 33 - 100和B 0 - 32.

虽然我有很多文件需要进行此操作,但单个文件非常小。

这是一个示例文件:

A   0       100
A   101     160 
A   200     300
A   500     1100
A   1200    1300
A   1301    1340
A   1810    2000
B   0       32
B   500     540
B   1250    1300
B   1319    1340
B   1920    2000

预期样本输出

A   33      100
A   101     160 
A   200     300
A   541     1100
A   1200    1249
A   1301    1318
A   1810    1919
B   0       32
B   500     540
B   1250    1300
B   1319    1340
B   1920    2000

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

好的,因为OP确认B 501 540是错误的,我发布了答案:)

awk -v OFS="\t" '/^A/{s[NR]=$2;e[NR]=$3;l=NR}
/^B/{ 
        for(i=1;i<=l;i++){
                if(s[i]==$2){
                        s[i]=$3+1
                        break
                }else if(e[i]==$3){
                        e[i]=$2-1
                        break
                }
        }
        s[NR] = $2; e[NR]=$3
}
END{for(i=1;i<=NR;i++)print ((i<=l)?"A":"B"),s[i],e[i]}
        ' file

使用您的文件进行测试(拼写错误已修复):

kent$  awk -v OFS="\t" '/^A/{s[NR]=$2;e[NR]=$3;l=NR}
/^B/{ 
        for(i=1;i<=l;i++){
                if(s[i]==$2){
                        s[i]=$3+1
                        break
                }else if(e[i]==$3){
                        e[i]=$2-1
                        break
                }
        }
        s[NR] = $2; e[NR]=$3
}
END{for(i=1;i<=NR;i++)print ((i<=l)?"A":"B"),s[i],e[i]}
        ' file
    A       33      100
    A       101     160
    A       200     300
    A       541     1100
    A       1200    1249
    A       1301    1318
    A       1810    1919
    B       0       32
    B       500     540
    B       1250    1300
    B       1319    1340
    B       1920    2000
6列的

编辑

又脏又快,请查看以下示例:

文件:

kent$  cat file
A   0       100 1 2 3
A   101     160 4 5 6
A   200     300 7 8 9
A   500     1100 10 11 12
A   1200    1300 13 14 15
A   1301    1340 16 17 18
A   1810    2000 19 20 21
B   0       32  22 23 24
B   500     540 22 23 24
B   1250    1300 22 23 24
B   1319    1340 22 23 24
B   1920    2000 22 23 24

awk:

kent$  awk -v OFS="\t" '{s[NR]=$2;e[NR]=$3}
/^A/{l=NR}
/^B/{ 
        for(i=1;i<=l;i++){
                if(s[i]==$2){
                        s[i]=$3+1
                        break
                }else if(e[i]==$3){
                        e[i]=$2-1
                        break
                }
        }
}
{r[NR]=$4OFS$5OFS$6}
END{for(i=1;i<=NR;i++)print ((i<=l)?"A":"B"),s[i],e[i],r[i]} ' file
A       33      100     1       2       3
A       101     160     4       5       6
A       200     300     7       8       9
A       541     1100    10      11      12
A       1200    1249    13      14      15
A       1301    1318    16      17      18
A       1810    1919    19      20      21
B       0       32      22      23      24
B       500     540     22      23      24
B       1250    1300    22      23      24
B       1319    1340    22      23      24
B       1920    2000    22      23      24