1)
文本:A 155
A 15
A 17
A 18
A 19
A 20
A 100
A 100
A 101
A 102
B 1
B 4
B 6
B 7
B 8
C 55
C 56
C 70
C 71
C 72
要求连续的行用跨度表示:
A: 155 15 17-20 100-102
B: 1 4 6-8
C: 55-56 70-72
- awk '{
-
if(!length(a[$1]))
-
a[$1]=$2;
-
else{
-
n=$2-1;
-
if(match(a[$1],"\\<"$2"\\>"))next;
-
if(sub("-"n,"-"$2,a[$1]))next;
-
if(sub(n,n"-"$2,a[$1]))next;
-
a[$1]=a[$1]" "$2};
-
}END{
-
for(n=0;n++<asorti(a,b);) print b[n]": "a[b[n]];
-
}' file
[解析]
利用数组来实现,当每个新的特征段落开始,a[$1] 的值为空时,把 $1 特征赋值给以它为下标的数组,这时候为了计算是否和上行的 $2 连续,我们设定一个变量为 n=$2-1 ;为了精确匹配我们这里使用了 match() 函数匹配动态正则的方法,(动态正则 )后面的两个替换是点睛之笔,大家演算一下就知道妙用了。最后用 for 循环打印出数组的值。佩服 jason680 的思路。
- awk '{
-
if($1==x){
-
if(index(i,$2))next;
-
if($2==y+1)
-
i=i"-"$2;
-
else
-
i=i" "$2;
-
}else{
-
if(NR>1){
-
gsub(/-[^ ]*-/,"-",i);
-
print i;
- }
-
i=$1": "$2;
-
}
-
x=$1;
-
y=$2;
-
}' file <(echo)
[解析]
这是非数组版,原理是判断这一行和上一行是否是连续的,然后根据需要来拼接字符串,最后把中间的替换掉,形成一个跨度显示。如果顺序是乱的还是预先排序好后管道给awk,sort -k1,1 -k2,2n file 。
- awk '{
-
if ($1==x){
-
if($2==y+1){
-
if(!i){
-
i=!i
-
printf "-"
-
}
-
}else if($2>y){
-
if(i){
-
printf y
-
i=!i
-
}
-
printf " "$2
-
}
-
}else{
-
if(i){
-
print y
-
i=!i
-
}else if(NR>1)print ""
-
printf $1": "$2
-
}
-
x=$1
-
y=$2
-
}END{
-
if(i)print y
-
else print ""
-
}' file
2)
cat file
82 82
98 98
99 99
100 100
114 114
123 123
124 124
要求如果是连续的行,压缩成一行:
82 82
98 100
114 114
123 124
- awk 'NR>1{
-
if(x+1!=$1){
-
if(!z){
-
print x FS x
-
}else{
-
y=y"-"x;sub(/-.*-|-/," ",y);print y;z=0;y=""
-
}
-
}else{
-
y=length(y)?y"-"x:x;z=1
-
}
-
}
-
{x=$1}
-
END{
-
if(z){
-
y=y"-"x;sub(/-.*-|-/," ",y);print y
-
}else{
-
print x FS x
-
}
-
}' file
[解析]
这个思路可能有点复杂,不知道有没有更好的方法,就是如果是连续的把数字用“-”串起来,最后再统一替换掉中间的部分,就留下起始和结束的数字,就算是用快度表示了。
- awk '{if(num+1!=$1){if(num)printf num"\n"$1" ";else printf $1" "}num=$1}END{{print $1}}' file
[解析]
这是很棒的思路,利用错行打印。
- awk '$1!=b+1{if(NR>1)print a,b;a=$1}{b=$2}' file <(echo)
[解析]
更棒的思路。
3)
cat file
var 1
var 2
var 3
var 4
var 5
var 8
var 9
var 10
var 11
var 12
var 13
var 14
var 25
var 26
var 27
var 28
var 29
var 55
var 56
var 57
var 58
var 59
var 60
var 61
var 90
var 91
结果:
var 1-5
var 8-14
var 25-29
var 55-61
var 90-91
- awk 'NR>1{if($2!=x+1){print y"-"x;c=0}}{x=$2}!c++{y=$0}' file <(echo)
阅读(1428) | 评论(0) | 转发(0) |