首页 > 代码库 > shell 脚本awk的高级应用之
shell 脚本awk的高级应用之
需求:
文本中第一列字符相等时,第二列相加 ,最后输出字符和最后的和(为了方便最后核对,都给了1)
文本如下:
cat test.log abc 1 aaa 1 bbb 1 ddd 1 sss 1 iii 1 abc 1 sss 1 ddd 1 ddd 1 ddd 1 ddd 1 bbb 1 bbb 1 bbb 1 bbb 1 bbb 1
思路1: awk把第一列取出,然后排序sort,去重uniq,赋值给变量x,然后遍历x,从文本中grep,然后awk截取第二列并相加,这个思路需要多次awk,多次读文件,效率较慢,思考着能不能一次读取就搞定呢,于是思路2
思路2: cat文本后sort,按照第一列排序,这样相等的就连续出现,不相等时说明是下一个了,于是awk读入,判断第一列是否跟上次相等,相等则加;不等则打印total;注意首行和末行
思路2代码:
#!/bin/bash cat test.log|sort|awk ‘BEGIN{ #排序文本,并读入 tmp = "" total = 0 } { if (tmp==$1) #当相等时相加 { total += $2 } else{ #不相等时,打印上次的相加值 if (tmp!=""){ #处理首行,当首行时,没有上一次,所以需要排除 print tmp " total is : " total #打印 } tmp = $1 #给变量赋新值 total = $2 } } END{ #处理末行,END关键字表示文档读取完毕, #理由:最后一次不等时打印的是上次,最后一次没有机会打印 print $1 " total is : " total }‘ ##备注:这是面试官出的一道题,我想用思路一,结果他说在awk内部实现,我虽有思路但是语法不太记得了, #而且用手写,结果就惨了
思路1代码:
#!/bin/bash tmp=`cat test.log |awk ‘{print $1}‘|sort|uniq` #去重后的值 sum=0 for i in `echo $tmp` #遍历去重后的值 do num=`grep $i test.log|awk ‘{print $2}‘` #过滤出第一列相等的所有值 for j in $num #遍历所有值 do sum=$(($j+$sum)) #相加 done echo $i "total is :" $sum #打印 sum=0 #重新初始化 done
结果:
[root@localhost ~]# sh a.sh aaa total is : 1 abc total is : 2 bbb total is : 6 ddd total is : 5 iii total is : 1 sss total is : 1 [root@localhost ~]# sh b.sh aaa total is : 1 abc total is : 2 bbb total is : 6 ddd total is : 5 iii total is : 1 sss total is : 1
总结:代码量都差不多,但是明显思路2高级。在awk内部编程,语法不一样,千万注意
1、遍量的定义、使用
2、大括号区分代码块
python 实现:
#!/usr/bin/env python2 con = open("test.log","r") f1 = [] f2 = [] f3 = [] sum = 0 for lines in con.readlines(): line = lines.strip().split(" ") f1.append(line[0]) f3.append(line) f2 = list(set(f1)) #利用集合的特性去重 for n in f2: for m in f3: if n == m[0]: sum += int(m[1]) print n + " total is : " + str(sum) sum = 0 con.close()
shell 脚本awk的高级应用之
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。