在linux shell中用awk如何实现这个问题:

想处理一个文件,每一行有4个部分,用逗号隔开。其格式如下:
chr1,3001633,3001652,-
chr1,3001635,3001646,+
chr1,3004207,3004222,+
chr1,3004212,3004222,+
chr1,3004213,3004226,+
chr2,3000500,3000507,+
chr3,3000500,3000507,-

其中,每行第二第三列表示一个区间,如第一行的区间为[3001633,3001652]
且文本已按先第一列再第二列的优先级升序排序。

输出要求是这样的:
如果任意2行之间的第一第四列相同,则比较第三列区间。若区间有重叠部分,则融合合成一个新的区间,如第三第四第五行可融合为chr1,+,[3004207:3004226]。
以上文本的输出应为:
chr1,3001633,3001652,-
chr1,3001635,3001646,+
chr1,3004207,3004222,+
chr2,3000500,3000507,+
chr3,3000500,3000507,-

请问对于任意一个以上格式的文本,如何在linux shell中使用awk实现这样的输出?
非常感谢。

你这个题目很有意思,你看我脚本对么:
awk -F "[,]" 'BEGIN{b="";}{
if (a[$1$4]) {
split(a[$1$4],value,",");
if( $2 <= value[2]) {
a[$1$4]=value[1]","$3;
b=$1","a[$1$4]","$4;
} else {
b=$1","a[$1$4]","$4;
printf("%s\n",b);
a[$1$4]=$2","$3;
b=$1","a[$1$4]","$4;
};
}else {
printf("%s\n",b);
a[$1$4]=$2","$3;
b=$1","$2","$3","$4;
};
}END{printf("%s\n",b);}' test.txt追问

不太对。如果是如下文本:
chr1,3001633,3001652,-
chr1,3001635,3001646,+
chr1,3001637,3001656,-
chr1,3004207,3004222,+
chr1,3004212,3004222,+
chr1,3004213,3004226,+
第一和第三行应该合并
而您的代码无视了文本第三行。
觉得还需要一个变量c。第一列相同时,b保存第四列为“+”的,c保存为“-”的。再根据下一行第四列的情况,决定应与b还是c比较、融合。我自己改好了,感谢您的启发。分数奉上。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-09-29
没太明白你的具体意思?
1. 任意两行是要连续行,还是可以不是连续行
2. 上面的第三第四第五行为
chr1,3004207,3004222,+
chr1,3004212,3004222,+
chr1,3004213,3004226,+
这个符合你说的第一列和第四列相同,第三列有相同的就融合,但
chr1,3004213,3004226,+
这一行怎么不见了。
能不能再说得明白点追问

1. 无需连续,也未必是连续的2行。可以是多行,只要满足融合条件,多行就融合为一行。因为已经排序过,所以可以融合的多行必定是连续的。
2. 第三第四第五行,三行可以融合为一行。因为满足融合的条件,即第一第四列相同;且三个区间互相重叠。

相似回答