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

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

文章分类

全部博文(272)

文章存档

2015年(2)

2014年(5)

2013年(25)

2012年(58)

2011年(182)

分类: LINUX

2011-11-02 21:12:33

1)

文本:
NO4 103
NO4 45
NO2 12
NO2 78
NO3 33
NO3 41
NO3 10

要求找出第一列相同的最大值的行,并按原顺序输出(NO的顺序不能乱):
NO4 103
NO2 78
NO3 41



  1. awk 'NR>1{if(x==$1){if($2>y)z=$0;else next}else{print z}}{x=$1;y=$2;z=$0}END{print z}' file
[解析]
这是非数组版,因为特征一样的行都是相邻的,没有交叉的情况,所以可以不用数组,这样逐行比较,输出最大值的行。而且顺序并没有发生变化,当然本文的重点不在这里。


  1. awk '{if(a[$1]<$2){a[$1]=$2;b[$1]=$0}}END{for(i in a)print b[i]}' file
  2. NO3 41
  3. NO4 103
  4. NO2 78
[解析]
没错,答案是完全正确的,但是没有按原序输出文本,特别是 for( i in array) 函数,输出的本来就是随机的下标,就象是一个糖果盒,你永远不知道拿出的是什么口味的水果糖。





  1. awk '{if(a[$1]<$2){a[$1]=$2;b[$1]=$0}}END{for(i=1;i<=asorti(a,c);i++)print b[c[i]]}' file
  2. NO2 78
  3. NO3 41
  4. NO4 103
[解析]
噢...,题目也并未要求让我们排序按从小到大的输出结果。。。那这就是数组的硬伤吗?NO,请下看。


  1. awk '{if(a[$1]<$2){a[$1]=$2;b[$1]=$0;if(!c[$1]++)d[++j]=$1}}END{for(i=1;i<=j;i++)print b[d[i]]}' file
  2. NO4 103
  3. NO2 78
  4. NO3 41
[解析]
搞定。虽然用了4个数组,数组a是来比较$2的值,数组b是来保存最大值的行,数组c是来去重,数组d是按数字下标递增的保存去重后的特征。虽然复杂点,但能达到要求。


  1. awk '!($1 in a){c[++j]=$1}a[$1]<$2{a[$1]=$2;b[$1]=$0}END{for(i=0;i++print b[c[i]]}' file
[解析]
这个代码稍微短一点,少用一个数组,是利用 in 来判断,原理都是和上一个命令一样。


2)

原文如上,要求按照相同特征进行第二列的拼接:
NO4 103 45
NO2 12 78
NO3 33 41 10



  1. awk 'NR>1{if(x==$1){z=z FS $2;next}else print z}{x=$1;y=$2;z=$0}END{print z}' file
[解析]
这是非数组版,惯例这也不是本文的重点。

  1. awk '{if(a[$1]){a[$1]=a[$1] FS $2}else{a[$1]=$2;b[++j]=$1}}END{for(i=1;i<=j;i++)print b[i],a[b[i]]}' file
  2. NO4 103 45
  3. NO2 12 78
  4. NO3 33 41 10
[解析]
这也是专门通过另外一个数组来按数字递增的下标记录特征,为了后面通过数字来顺序输出。如果被数组的顺序困扰的朋友,希望本文能帮到你。

3)

文件:
张三
张三
张三
李四
李四
王五

统计出现次数,按原顺序输出:
张三  3
李四  2
王五  1



  1. awk '!a[$1]++{b[++j]=$1}END{for(i=0;i++<j;)print b[i],a[b[i]]}' file
[解析]
在去重的同时,其实就完成了计数,只需要用另外一个数组按顺序保存好下标就行了,这样就方便END的输出。
阅读(2425) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~