Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2987779
  • 博文数量: 272
  • 博客积分: 5544
  • 博客等级: 大校
  • 技术积分: 5496
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-08 00:48
个人简介

  每个人都要有一个骨灰级的爱好,不为金钱,而纯粹是为了在这个领域享受追寻真理的快乐。

文章分类

全部博文(272)

文章存档

2015年(2)

2014年(5)

2013年(25)

2012年(58)

2011年(182)

分类: LINUX

2011-11-22 23:35:18

1)

文本:
b  9    12
h  76   83
a  5    7
d  25   35
e  39   43
f  60   63
j  97   99
i  84   87
c  15   19
k  102  107
l  109  120
g  67   72

第一列是线段名称,第二、三列是线段的起点和终点,线段之间没有重叠,文件中线段是无序的,如果连续的两条线段之间距离小于6,就说他们相邻,如果相邻线段数大于2就说这些线段形成连续块,要求打印出所有连续的块:
a-b-c
f-g-h-i
j-k-l



  1. awk 'NR>1{if($2-y<6 && $2-y>0){i=i?i"-"$1:x"-"$1;z++}else{if(z>1)print i;i=0;z=0}};{x=$1;y=$3}' <(sort -k2n file;echo)
[解析]
首先得按照第一列的名称来排序,第一行,就不比较了,执行第二个{action},然后第二行满足 NR>1 条件,开始执行比较,看当前行的开始点减上一行的终止点,结果是否小于6,为什么还要判断是否大于0,我们稍候讲,满足这个条件后来判断 i 的值是否为空,然后按条件给 i 赋值。然后执行 z++ 记数,直到超出我们的判断条件后,判断是否 z>1 ,这样的目的就是来看是否是3个线段,如果只是2个线段相邻的就不打印了,然后把 i 和 z 都清空。直到最后我们 echo 打印的空行,这时候空行的 $2 为空,即为零,去减上一行会存在负数,所以我们在 if 判断里会加上大于0的判断,这样不满足条件,迫使流程去执行 else 里的 if 判断,看是否我们的计数器 z 大于1,大于1我们才能判断是两个以上的相邻线段,才能打印 i 里保存的数据。




  1. sort -k2n file|awk 'function p(){if(k>2)print r}{a[NR]=$3;if(NR==1 || $2-a[NR-1]>=6){p();r=$1;k=1}else{r=r"-"$1;k++}}END{p()}
[解析]
这条命令利用了函数,专门用一个函数来判断是否是相邻的两个以上的线段,然后才会打印。首先用数组保存第三列的值,然后满足第一行或当前行的第二列减上一行的第三列大于等于6,就执行函数里的判断,不满足条件呢就进行 r 的字符串拼接,和 k++。最后 END 也再执行一次函数,判断是否满足条件打印。 
 


  1. awk '{name[$2]=$1;left[$1]=$2;right[$1]=$3}END{
  2. x=asort(left);
  3. asort(right);
  4. y=1;
  5. s=name[left[1]];
  6. for(i=2;i<=x;i++) {
  7.      if(left[i]-right[i-1]>=6) {
  8.             if(i-1>y+1)
  9.                    print s;
  10.             y=i;
  11.             s=name[left[i]];
  12.      } else {
  13.             s=s"-"name[left[i]];
  14.      }
  15. }
  16. if(y<x-1)
  17.      print s;
  18. }' file


2)

cat file
2012/01/10-11:10:27 2012/01/10-11:10:27 AA
2012/01/10-11:10:27 2012/01/10-11:20:27 BB
2012/01/10-11:10:27 2012/01/10-11:30:27 CC


要求把第二个时间大于等于第一个时间十分钟的行输出:




  1. awk 'function s(a){split(a,b,"-");cmd="date -d \""b[1]" "b[2]"\" +%s";cmd|getline line;close(cmd);return line};s($2)-s($1)>=600' file
[解析]
定义一个函数来计算时间戳,最后把这两个时间戳想减,大于600秒的打印。
阅读(3323) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~