工作中经常处理文本数据,以前经常接触db2数据库,最近在学习awk的过程中发现awk处理数据的强大,可谓无所不能!下面讲的就算awk对sql语句统计数据的模拟。
一、先讲讲sql的单表操作,对应awk的单文件处理。
测试环境:sco unix + db2,数据文件名file,数据库表名mytable,为保证准确性,所有语句均做测试。
就以存折明细这样的数据来举例吧,为了实现一些复杂的sql语句,数据有点多。
字段说明:1日期date 2摘要zy 3借贷标志bz 交易金额je 4余额ye 5操作员czy
|
|
1、 统计07、08年每月交易发生笔数,按月排序
sql语句:
|
|
awk语句:
|
|
2、统计07、08年各类交易发生的笔数、金额
sql语句:
|
|
awk语句:
|
|
3、嗯,在我的存折明细中,按月统计下07、08年每个操作员、每月的交易发生笔数吧,扣电费、电话费(czy为auto)的不统计,结果按月份、操作员号排序
sql语句:
|
|
awk语句:
|
|
对以上3个例子做个小总结:
awk如何实现sql语句的group分组功能呢?
关键是定义好数组,如:第1例中sql对月份(substr(date,1,6))分组,那awk中就定义数组a[substr($1,1,6)]。至于 要给该数组赋怎样的值,看统计需求。如例1统计分组后的次数,就a[substr($1,1,6)]++,表示 a[substr($1,1,6)]=a[substr($1,1,6)]+1;若要合计金额,如例2,则a[$2)]+=$4,等价于 a[$2]=a[$2]+$4,$4表示第4字段,是金额字段;至于例3,又稍微复杂了点,要根据两个条件分组(月份substr($1,1,6)、操作 员$6),那定义的数组就是a[substr($1,1,6)" "$6],注意下标中的" ",是为了输出时显示效果,你也可以改成别的,如改成"#",最后显示效果就是这样:
|
4、又想到稍微复杂点的,用到了sql语句的having筛选。
统计每年发工资的总额,显示超过750元的年份。
sql语句:
|
|
awk语句:
|
|
|
|
对应文件mx.txt和khxx.txt
mx.txt内容如下:
|
khxx.txt内容如下:
|
-------------例子开始-------------
1、统计出2007年1月份发生额总和大于2000的客户,列出帐号、姓名、月份、发生额合计
sql的表关联操作
|
awk的处理
|
这条AWK语句开始让我很迷糊,看不懂。花了些时间,终于搞懂了。下面解析下,做个笔记:
1、NR:The total number of input records seen so far.(目标文件总共有多少行)
2、FNR:The input record number in the current input file.(当前读取文件的行数)
这里注意,awk的FNR是以花括号的前后顺序对应目标文件的。
拿上面的语句为例:
'NR==FNR&&substr($2,1,6)=="200701"{a[$1]+=$4}处理的是mx.txt文件
NR>FNR&&a[$1]>2000{print $1,$2,"200701",a[$1]}' 处理的是khxx.txt,这样看,大家就应该很容易明白了。
3、a[$1]这个数组很关键,也就是连接两个表的关键字段。第一段代码统计出每个$1的金额,在第二段
代码中,先过滤此数组的结果,然后使用第二个表的$1字段为索引,把相关信息列出来。
|
|
就写到这吧,编数据,想例子好累。
补充一个awk调用printf的例子
转自:
- [root@station11 shell]#awk -F ":" '{a[$2]++} END {for (i in a) printf ("%-30s %5d/%-5d = percent:%.2f%%\n",i,a[i],FNR,a[i]/FNR*100)}' 2.txt | sort -k 4 -r
- updateh.360safe.com^M percent:0.641026
- www.360safe.com^M percent:0.179487
- se.360.cn^M percent:0.102564
- bo.duba.net percent:0.051282
- w6.safe.lfc.qihoo.net^M percent:0.025641
- [root@station11 shell]# cat 2.fi
- cat: 2.fi: No such file or directory
- [root@station11 shell]# cat 2.file
- cat: 2.file: No such file or directory
- [root@station11 shell]# cat 2.txt
- Host: bo.duba.net:8080^M
- Host: bo.duba.net:8080^M
- Host: updateh.360safe.com^M
- Host: www.360safe.com^M
- Host: updateh.360safe.com^M
- Host: se.360.cn^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: www.360safe.com^M
- Host: updateh.360safe.com^M
- Host: www.360safe.com^M
- Host: www.360safe.com^M
- Host: se.360.cn^M
- Host: www.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: w6.safe.lfc.qihoo.net^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: www.360safe.com^M
- Host: updateh.360safe.com^M
- Host: se.360.cn^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: www.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: se.360.cn^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
- Host: updateh.360safe.com^M
http://linuxguest.blog.51cto.com/195664/424496