- 论坛徽章:
- 0
|
本帖最后由 ashlv 于 2010-09-03 09:31 编辑
昨晚回去整理了一下,基本上,只要文件内区间没有交集,并且不存在类似7-7这样的区间,其它都还没有发现什么问题
虽然7-7这种类型的也可以处理,但是又要写一大坨代码,所以先不处理了
calx.sh:
- t1=$1
- t2=$2
- t3=$3
- #获取2个文件中所需数据 文件名/每行所属section/开闭区间/文件内容
- awk 'FS="-";/./{
- a[FNR]=substr($0,0,7)=="section"?$0:a[FNR-1];
- a["v"]=substr(a[FNR],8);
- if(a[FNR]==$1)
- print a["v"],$1,$1,$1;
- else
- print a["v"],FILENAME=="'${t2}'"?"x ]":"y [",$1" \n"a["v"],FILENAME=="'${t2}'"?"x [":"y ]",$2;
- }' $t1 $t2|
- #将数据集中堆放,分离开标题
- sort -k4nr -k2|
- #排除t1集合外所有可以配对的属于t2的区间
- #排除t2集合内所有可以配对的属于t1的区间
- #此时t2内有效的点必定落在t1范围内,可以根据范围对t2进行对于t1的section定界
- #由于同一文件中不存在交集,重合的点section以t1为准
- awk '{
- a[NR]=$1;b[NR]=$2;c[NR]=$3;d[NR]=$4;e[NR]=$0;f[NR]=$2=="x"?f[NR-1]==""?0:f[NR-1]:$1;
- }END{
- a["x1"]=0;a["y1"]=0;a["x2"]=1;a["y2"]=1;a["z"]=0;
- for(i in e){
- if(b[i]=="y"&&c[i]=="["&&b[i-1]=="y"&&c[i-1]=="]") a["y1"]++;
- if(b[i]=="x"&&c[i]=="["&&a["x1"]>0) a["x1"]--;
- if(b[i]=="x"&&c[i]=="["&&((b[i-1]=="x"&&c[i-1]=="]")||b[i-1]=="")) a["y2"]++;
- if(b[i]=="y"&&c[i]=="["&&a["x2"]>0) a["x2"]--;
- if(b[i]=="y"&&c[i]=="]"&&a["z"]>0) a["z"]--;
- if((a["x1"]+a["y1"]<2&&a["x2"]+a["y2"]<2)||substr(b[i],0,7)=="section")
- print f[i],b[i],c[i],d[i];
- if(b[i]=="x"&&c[i]=="]") a["x1"]++;
- if(b[i]=="y"&&c[i]=="]"&&a["y1"]>0) a["y1"]--;
- if(b[i]=="y"&&c[i]=="]") a["x2"]++;
- if(b[i]=="x"&&c[i]=="]"&&a["y2"]>0) a["y2"]--;
- if(b[i]=="y"&&c[i]=="[") a["z"]++;
- }
- }'|
- #将拥有相同值的数据点合并,以t2为准
- sort -k4n -k2|
- uniq -f 3|
- #格式化列表,供后续使用,并将开区间转换为闭区间
- awk '{
- if($3=="[")
- printf $3" "$2" "$1" "($2=="x"?$4+1:$4)" z ";
- else if($3=="]")
- printf ($2=="x"?$4-1:$4)" "$1" "$2" "$3" z ";
- else
- print $0;
- }'|
- #排除原先开区间中每2个区间中的所有数据点
- sed "s/x \][^x]\+\[ x/x \] z \[ x/g"|
- #合并所有起点,以最大值的起点为准
- sed "s/\][^][]\+\]/\]/g"|
- #合并所有终点,以最小值的终点为准
- sed "s/\[[^][]\+\[/\[/g"|
- #格式化
- sed "s/\] z\( \[\)\{0,1\}/#/g"|
- sed "s/\[//g"|tr "#" "\n"|
- sed "s/ z /-/g"|
- sed "s/ [xy] //g"|
- sort -k1n -k2r|
- #获得t1与t2的差集,输出到t3
- awk '{print $2;}'|
- awk 'FS="-";{if($2==""||($1<=$2))print $0}'>$t3
- #合并t3与t2,即获得结果
- awk '{
- a[FNR]=substr($0,0,7)=="section"?$0:a[FNR-1];
- print FILENAME,substr(a[FNR],8),$0;
- }' $t3 $t2|
- sort -k2r -k4r|
- uniq -f 2|
- sort -k2r|
- awk '{print $3}'
复制代码 在LZ测试数据的基础上增加了更多的边界和交集:
- $ cat t1
- section1
- 5-9
- 10-25
- 30-30
- 200-300
- section2
- 900-1000
- 1950-1960
- 500-600
- 1100-1240
- 700-800
- section3
- 1300-1400
- 1450-1900
- 2000-2400
- 2500-3000
- section6
- 20000-21000
- section7
- 22000-23000
- $ cat t2
- section4
- 1-2
- 4-6
- 7-10
- 500-550
- 750-800
- 920-950
- 1955-1965
- 1100-1200
- section5
- 1250-1500
- 1600-1800
- 2200-2600
- 2999-3100
- 3200-3300
- section8
- 20500-22500
- $ ./calx.sh t1 t2 t3
- section8
- 20500-22500
- section7
- 22501-23000
- section6
- 20000-20499
- section5
- 3200-3300
- 2999-3100
- 2200-2600
- 1600-1800
- 1250-1500
- section4
- 920-950
- 750-800
- 7-10
- 500-550
- 4-6
- 1955-1965
- 1100-1200
- 1-2
- section3
- 2601-2998
- 2000-2199
- 1801-1900
- 1501-1599
- section2
- 951-1000
- 900-919
- 700-749
- 551-600
- 1950-1954
- 1201-1240
- section1
- 200-300
- 11-25
复制代码 |
|