1)
文本:NO4 103
NO4 45
NO2 12
NO2 78
NO3 33
NO3 41
NO3 10
要求找出第一列相同的最大值的行,并按原顺序输出(NO的顺序不能乱):
- 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
[解析]
这是非数组版,因为特征一样的行都是相邻的,没有交叉的情况,所以可以不用数组,这样逐行比较,输出最大值的行。而且顺序并没有发生变化,当然本文的重点不在这里。
- awk '{if(a[$1]<$2){a[$1]=$2;b[$1]=$0}}END{for(i in a)print b[i]}' file
-
NO3 41
-
NO4 103
-
NO2 78
[解析]
没错,答案是完全正确的,但是没有按原序输出文本,特别是 for( i in array) 函数,输出的本来就是随机的下标,就象是一个糖果盒,你永远不知道拿出的是什么口味的水果糖。
- 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
-
NO2 78
-
NO3 41
-
NO4 103
[解析]
噢...,题目也并未要求让我们排序按从小到大的输出结果。。。那这就是数组的硬伤吗?NO,请下看。
- 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
-
NO4 103
-
NO2 78
-
NO3 41
[解析]
搞定。虽然用了4个数组,数组a是来比较$2的值,数组b是来保存最大值的行,数组c是来去重,数组d是按数字下标递增的保存去重后的特征。虽然复杂点,但能达到要求。
- 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
- awk 'NR>1{if(x==$1){z=z FS $2;next}else print z}{x=$1;y=$2;z=$0}END{print z}' file
[解析]
这是非数组版,惯例这也不是本文的重点。
- 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
-
NO4 103 45
-
NO2 12 78
-
NO3 33 41 10
[解析]
这也是专门通过另外一个数组来按数字递增的下标记录特征,为了后面通过数字来顺序输出。如果被数组的顺序困扰的朋友,希望本文能帮到你。
3)
文件:
张三
张三
张三
李四
李四
王五
统计出现次数,按原顺序输出:
张三 3
李四 2
王五 1
- awk '!a[$1]++{b[++j]=$1}END{for(i=0;i++<j;)print b[i],a[b[i]]}' file
[解析]
在去重的同时,其实就完成了计数,只需要用另外一个数组按顺序保存好下标就行了,这样就方便END的输出。
阅读(2414) | 评论(0) | 转发(0) |