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

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

文章分类

全部博文(272)

文章存档

2015年(2)

2014年(5)

2013年(25)

2012年(58)

2011年(182)

分类: LINUX

2011-07-08 11:54:22

LOG记录:
1 2011. 6.26 21: 7:14 info[3]: account[1] login.
2 2011. 6.26 21:10:45 info[5]: account[1] drop.
3 2011. 6.26 21:11:25 info[5]: account[1] drop.
4 2011. 6.26 21:11:29 info[5]: account[1] drop.
5 2011. 6.26 21:15:21 info[3]: account[1] login.
6 2011. 6.26 21:15:58 info[5]: account[1] drop.
7 2011. 6.26 21:52:13 info[3]: account[2] login.
8 2011. 6.26 21:53:22 info[3]: account[2] login.
9 2011. 6.26 21:53:32 info[3]: account[2] login.
10 2011. 6.26 21:54:12 info[5]: account[2] drop.
11 2011. 6.26 21:55:57 info[3]: account[3] login.
12 2011. 6.26 21:56:43 info[5]: account[1] drop.
 
系统生成的日志有点问题,现在想要去掉重复部分(红色部分为重复了的),login行的话要最后一次的记录,drop行的只要第一次记录,得到下面的格式:
1 2011. 6.26 21: 7:14 info[3]: account[1] login.
2 2011. 6.26 21:10:45 info[5]: account[1] drop.
5 2011. 6.26 21:15:21 info[3]: account[1] login.
6 2011. 6.26 21:15:58 info[5]: account[1] drop.
9 2011. 6.26 21:53:32 info[3]: account[2] login.
10 2011. 6.26 21:54:12 info[5]: account[2] drop.
11 2011. 6.26 21:55:57 info[3]: account[3] login.
12 2011. 6.26 21:56:43 info[5]: account[1] drop.
 
  1. awk '{a[NR]=$0;b[NR]=$NF}END{for(i=1;i<=NR;i++){if((b[i]=="login." && b[i+1]!=b[i])||(b[i]=="drop." && b[i]!=b[i-1]))print a[i]}}' file
[解析]
  这个题有四星难度,不止是去重这么简单了,还有2个判断条件。首先把全行内容存入数组a,把最后我们判断的内容存入数组b,然后for循环开始判断,$NF的值是等于"login"并且该行的下一行的值不等于"login"才条件成立,打印该行,实际上就是只打印重复内容的最后一行。然后判断第2个条件$NF等于"drop"的时候,判断上一行是否是一样的,如果不一样就输出,这就相当于只输出重复行数的第一行,非常巧妙的思路。
 
 
 
 
  1. awk '$NF==y{if(/login/){x=$0;y=$NF};next}{if(NR>1)print x;x=$0;y=$NF}END{print x}' file
[解析]
  大家要是明白awk的流程控制,在纸上写写吧,效率比数组高很多,特别是大文件情况下。谢谢黑哥(blackold)指点,感激不尽。
  举一翻三,稍加修改可以控制只输出重复内容的第一行,或最后一行:
  1. #只输出重复行的第一行
  2. awk '$NF==y{next}{if(NR>1)print x;x=$0;y=$NF}END{print x}' file

  3. #只输出重复行的最后一行
  4. awk '$NF==y{x=$0;y=$NF;next}{if(NR>1)print x;x=$0;y=$NF}END{print x}' file
 
 
 
  1. awk 'x~/login/&&/drop/{print x RS $0}{x=$0}' file
[解析]
  这是最简短的代码,谢谢ywlscpl,仔细分析了一下范本,就是说上一行是匹配login,当前行匹配drop的就打印,我标记一下例子大家就明白了,要仔细分析范例找出规律,要少走很多弯路,别盲目一来就执笔开始写代码。彩色部分是满足条件的就输出:
1 2011. 6.26 21: 7:14 info[3]: account[1] login.
2 2011. 6.26 21:10:45 info[5]: account[1] drop.

3 2011. 6.26 21:11:25 info[5]: account[1] drop.
4 2011. 6.26 21:11:29 info[5]: account[1] drop.
5 2011. 6.26 21:15:21 info[3]: account[1] login.
6 2011. 6.26 21:15:58 info[5]: account[1] drop.
7 2011. 6.26 21:52:13 info[3]: account[2] login.
8 2011. 6.26 21:53:22 info[3]: account[2] login.
9 2011. 6.26 21:53:32 info[3]: account[2] login.
10 2011. 6.26 21:54:12 info[5]: account[2] drop.
11 2011. 6.26 21:55:57 info[3]: account[3] login.
12 2011. 6.26 21:56:43 info[5]: account[1] drop.

阅读(3761) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

mazzzz2011-07-09 08:57:27

请问$NF==y{a}{b}这样的语法是什么意思呢,有什么作用??
是if($NF==y) {a} else {b}这样的意思吗??

yinyuemi2011-07-09 07:12:04

学习学习!俺也来一个
awk '{if(/login/){l++;d=0}else{d++;l=0}}d==1{print x RS $0}{x=$0}END{if(!d)print x}'