[root@localhost tmp]# cat aaa
20070106|存款|2|400.00|500.27|010
20070106|取款|1|100.00|400.27|030
20070305|工资|2|400.00|800.27|999
20070505|电话费|1|50.00|750.27|auto
20070930|电费|1|50.00|700.27|auto
20071205|工资|2|300.00|1000.27|999
20080127|电话费|1|50.00|950.27|auto
20080303|取款|1|80.00|870.27|102
20080411|存款|2|600.00|1470.27|020
20080622|取款|1|300.00|1170.27|010
20080920|工资|2|800|1970.27|999
20090106|取款|1|200.00|1770.27|020
字段说明:1日期date 2摘要zy 3借贷标志bz 交易金额je 4余额ye 5操作员czy
1、统计07、08年每月交易发生笔数,按月排序
awk 语句:
[root@localhost tmp]# awk -F "|" ' BEGIN{print "月\t总数"} $1>=20070101&&$1<=20081230 {a[substr($1,1,6)]++}END{for (i in a) print i "\t"a[i]}' aaa|sort -n
月 总数
200701 2
200703 1
200705 1
200709 1
200712 1
200801 1
200803 1
200804 1
200806 1
200809 1
类 sql语句:
select substr(date,1,6),count(*) from mytable where date between '20070101' and '20081231' group by substr(date,1,6) order by substr(date,1,6)
2、统计07、08年各类交易发生的笔数、金额
awk 语句:
[root@localhost tmp]# awk -F "|" 'BEGIN{print "类别\t笔数\t金额"} $1>=20070101&&$1<=20081231 {a[$2]+=$4;b[$2]++} END{for (i in a) print i"\t"b[i]"\t"a[i]} ' aaa|sort -k 2,2 -n
类别 笔数 金额
电费 1 50
存款 2 1000
电话费 2 100
取款 3 480
工资 3 1500
类 sql语句:
select zy,count(*),sum(je) from mx where date between '20070101' and '20081231' group by zy
3、按月统计下07、08年每个操作员、每月的交易发生笔数,扣电费、电话费(czy为auto)的不统计,结果按月份、操作员号排序
[root@localhost tmp]# awk -F "|" 'BEGIN{print "月份\t操作员\t笔数"} $6!="auto"&&$1>=20070101&&$1<=20081231 {a[substr($1,1,6)"\t"$6]++}END{for (i in a) print i"\t"a[i]}' aaa|sort -k1n -k2n
月份 操作员 笔数
200701 010 1
200701 030 1
200703 999 1
200712 999 1
200803 102 1
200804 020 1
200806 010 1
200809 999 1
类 sql语句:
select substr(date,1,6)\"月份\",czy,count(*)\"笔数\" from mytable where czy
<>'auto' and date between '2007010' and '20081231' group by substr(date,1,6),czy
order by substr(date,1,6),czy
对以上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)"\t"$6],注意下标中的"\t",是为了输出时显示效果,你也可以改成别的,如改成"#",最后显示效果就是这样:
[root@localhost tmp]# awk -F "|" 'BEGIN{print "月份\t操作员\t笔数"} $6!="auto"&&$1>=20070101&&$1<=20081231 {a[substr($1,1,6)"#"$6]++}END{for (i in a) print i"#"a[i]}' aaa|sort -t# -k1n -k2n
月份 操作员 笔数
200701#010#1
200701#030#1
200703#999#1
200712#999#1
200803#102#1
200804#020#1
200806#010#1
200809#999#1
4、稍微复杂点的,用到了sql语句的having筛选。
统计每年发工资的总额,显示超过750元的年份。
[root@localhost tmp]# awk -F "|" 'BEGIN{print "年份\t金额"}$2=="工资" {a[substr($1,1,4)]+=$4}END{for (i in a)if (a[i]>750) print i"\t"a[i]}' aaa
年份 金额
2008 800
类 sql语句:
select substr(date,1,4),sum(je) from mytable where zy='工资' group by substr(date,1,4) having sum(je)>750