一个用shell完成的统计程序

要是shell里能进行很好的循环就好了。以及shell最不容易控制的就是’,”,这3个标点符号的区别。这个倒是比较简单,就是在shell里只是表示运行外部程序。”和’这个如果单独使用是没有任何问题的,但是一旦要配合使用就区分起来十分麻烦。

这个日志统计程序中总共用了500多行,先定义30个日期。这个要是能用循环就非常简单了。但是我还是用比较傻的一个个来进行定义。

 day=`date -d -1days +%F` day_1=`date -d -2days +%F` 

这里要是能够使用的数组来进行定义就非常简单了。

 for i in {2..30}
 do
   eval day_$i=`date -d -"$i"days +%F`
   eval echo $day_$i
done  

通过上面就可以进行循环定义了。

这里需要定义和引用变量的过程比较多,一个数据往往要转换多次才可以得到最后真实的数据,这里一共进行了4次数据的赋值工作加一次if判断工作。还好现在总的执行时间还在0.02秒以内完成。不然就必须得修改这样一个程序了。

login_user=`mysql -h$db -u$dbuser -p$dbpass -e "select distinct id from test.iplog where time like '"$day"%'" |sed -n '2,$'p > login_user.diff` 

这个是用来统计今天有哪些用户登陆过了系统,并把结果写入到login_user.diff中

reg_30_user=`mysql -h$db -u$dbuser -p$dbpass -e "select id from test.user_desc where registertime like '"$day_30"%'" | sed -n '2,$'p > reg_30_user.diff && cat login_user.diff >> reg_30_user.diff` 

这里在数据库中进行一次like操作,这个其实是很费时间的如果条数过多的话。查询出来通过sed来取出用户名到一个文件中同时跟今天的登录用户名进行合并。

login_user_number=`mysql -h$db -u$dbuser -p$dbpass -e "select count(distinct id) from test.iplog where time like '"$day"%'" | sed -n '2'p` 

这个是用来统计今天登陆过系统的用户数。

 num_30_reg=`cat reg_30_user.diff | sort | uniq -d | wc -l` 

这个用来统计前面第30天注册的用户在今天到底有多少人登陆了。这个其实是可以跟上面这个语句进行合并的,但是怎么都测试不通过。也考虑过用select in操作来进行,首先是要进行行列转换

uniq_30_user=`mysql -h$db -u$dbuser -p$dbpass -e "select count(distinct id) from test.user_desc where registertime like  '"$day_30"%'" | sed -n '2'p` 

计算那天的注册用户数量。这样根据前面2个数据可以知道注册用户的实际登陆频率是怎么样的。

 if  [ $uniq_30_user -eq 0 -o $num_30_reg -eq 0 ];
 then 
   per_30=0.00 
 else 
   per_30=`awk 'BEGIN {x='"$num_30_reg"';y='"$uniq_30_user"';printf "%.2fn",x/y}'` 
   echo $per_30
fi; 

首先是判断过去某一天的注册用户数是否为0,以及那天的注册用户在今天登陆数是否0,在shell中,除法的两边都不能为0,这个还跟普通的公式不同。如果2个数都为0,那直接赋值0.00给它,不然就进行除法运算,并保留2位小数。这个表达式的单引号双引号可是困惑了整整一天时间。

最后就是mysql插入的语句,把这30个数据最后按照一定的规律插入到表中就可以了。