2

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

  • 有一堆以“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

感谢你的帮助!

4

1 回答 1

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
于 2013-05-19T21:07:09.583 回答