一个简单的统计脚本

1.需求描述

  商店服务BuyItemServer会根据玩家购买游戏道具的请求打印后台按天日志,记录玩家购买的道具种类、数量和付费类型等,产品需要统计某个时期内某分区内玩家的消费情况,列出每个区RMB消费总额前5000名的名单,分别发放奖励。

  该按天日志的文件名格式如下:

    

  日志内容格式如下所示:

  

  其中第3个字段表示用户号码,第4个字段是分区号,第5个字段是付费方式(1:元宝,2:G币,3:Q币),第8个字段是购买金额。由于G币是基本游戏币,不是一种RMB消费,所以在统计的时候需要排除G币购买的记录。

2. 逐步实现需求

  2.1 根据起始和截止日期提取待处理日志文件列表,处理函数如下:

#获取两个日期之间的日期列表
function getDateList()
{
        if [ $# -eq 2 ]
        then
                startDate=$1
                date1=`date -d "$1" +%s`
                date2=`date -d "$2" +%s`
                seconds_count=`echo $date2-$date1|bc`
                days=`echo $seconds_count/86400|bc`
                for((index=0;index<=$days;index++))
                do
                        array[$index]=`date -d "$startDate $index days" +%Y%m%d`
                done

        fi
        echo ${array[@]}
}

  注1. 主要使用了date命令来处理日期

  注2. 使用了shell中的数组,shell的函数无法返回数组,因此使用echo命令来代替return处理

  2.2 根据日期列表组个处理按天日志文件,处理函数如下:

#生成总消费额
function generateConsumeAccount()
{
        [ $# -lt 2 ] && printHelp "wrong paramter number."
        dateList=$(getDateList $1 $2)
        for date in ${dateList[@]}
        do
                echo "doing $date.log"
                awk -F'|' '{if($5==1 || $5==4){print$3"_"$4"|"$8}}' $MERGE_LOG_PATH$LOG_FILE_PREFIX$date.log >> $1_$2.temp
        done
}

  注1. 上面这个function调用了之前的getDateList来获取日期列表,然后使用for循环遍历日期列表,使用awk处理相应的日志文件,将结果放到临时文件中,这样处理之后,在.temp临时文件中玩家每次购买行为都会有保存一条日志,的格式为:号码_分区|消费额

  2.3 根据玩家号码和分区统计同一区的同一号码的总消费额

  这里使用了之前用C++写的一个工具count.sh来处理。略过

  2.4 根据消费总额文件分别提取各分区的对应名次,脚本generateList.sh如下:

#!/bin/sh
#分区统计
#AREA_ARRAY=(1)
AREA_ARRAY=(1 2 3 4 5)
function printHelp()
{
        echo "/*****************************************************************/"
        echo "[remark]:"根据消费总额文件生成各区排名[start, end]名的人名列表
        echo "[usage]:"$0 "INPUT_FILE START_INDEX END_INDEX"
        echo "[sample]:"$0 20130320_20130320.list 1 10
        echo "[sample]:"$0 20130320_20130320.list 101 500
        echo "[message]:"$1
        echo "/*****************************************************************/"
        exit -1

}

[ $# -lt 3 ] && printHelp "参数个数不正确"

for i in ${AREA_ARRAY[@]}
do
        awk '/_'"$i"'/' $1 | awk -F'|' '{if(NR>='"$2"' && NR<='"$3"'){print$1}}'
        #awk '/_'"${i}"'/' $1
done

  再编写脚本调用上述脚本分别传递具体参数进行处理。

  最终得到的几个脚本如下:

getConsumeAccount.sh
 1 #!/bin/bash
 2 MERGE_LOG_PATH="/usr/local/app/taf/remote_app_log/JWTLSB/MergeLog/"
 3 LOG_FILE_PREFIX="JWTLSB.MergeLog_daoju_7026_"
 4 COUNT_TOOL="/usr/local/app/jwtlsb_tools/getConsumeAccount/lib/count.sh"
 5 function printHelp()
 6 {
 7     echo "/*****************************************************************/"
 8     echo "[remark]:"获取指定日期内的消费额,并写入文件中
 9     echo "[usage]:"$0 "BEGIN_DATE[YYYYMMDD] END_DATE[YYYYMMDD]"
10     echo "[sample]:"$0 20130320 20130320
11     echo "[sample]:"$0 20130326 20130329
12     echo "[message]:"$1
13     echo "/******************************************************************/"
14     exit -1
15 }
16 #获取两个日期之间的日期列表
17 function getDateList()
18 {
19     if [ $# -eq 2 ]
20     then
21         startDate=$1
22         date1=`date -d "$1" +%s`
23         date2=`date -d "$2" +%s`
24         seconds_count=`echo $date2-$date1|bc`
25         days=`echo $seconds_count/86400|bc`
26         for((index=0;index<=$days;index++))
27         do
28             array[$index]=`date -d "$startDate $index days" +%Y%m%d`
29         done
30 
31     fi
32     echo ${array[@]}
33 }
34 
35 #生成总消费额
36 function generateConsumeAccount()
37 {
38     [ $# -lt 2 ] && printHelp "参数个数错误"
39     dateList=$(getDateList $1 $2)
40     for date in ${dateList[@]}
41     do
42         echo "doing $date.log"
43         awk -F'|' '{if($5==1 || $5==4){print$3"_"$4"|"$8}}' $MERGE_LOG_PATH$LOG_FILE_PREFIX$date.log >> $1_$2.temp
44     done
45 }
46 
47 [ $# -lt 2 ] && printHelp "参数个数错误"
48 generateConsumeAccount $1 $2
49 $COUNT_TOOL "$1_$2.temp" | sort -nr -k2 -t"|" > $1_$2.list
50 rm $1_$2.temp
51 echo "done, saved in file $1_$2.list"
generateList.sh
 1 #!/bin/sh
 2 #分区统计
 3 #AREA_ARRAY=(1)
 4 AREA_ARRAY=(1 2 3 4 5)
 5 function printHelp()
 6 {
 7     echo "/*****************************************************************/"
 8     echo "[remark]:"根据消费额文件生成各区消费[start, end]名的人列表
 9     echo "[usage]:"$0 "INPUT_FILE START_INDEX END_INDEX"
10     echo "[sample]:"$0 20130320_20130320.list 1 10
11     echo "[sample]:"$0 20130320_20130320.list 101 500
12     echo "[message]:"$1
13     echo "/*****************************************************************/"
14     exit -1
15     
16 }
17 
18 [ $# -lt 3 ] && printHelp "参数个数不正确"
19 
20 for i in ${AREA_ARRAY[@]}
21 do
22     awk '/_'"$i"'/' $1 | awk -F'|' '{if(NR>='"$2"' && NR<='"$3"'){print$1}}'
23     #awk '/_'"${i}"'/' $1
24 done
getRewardList.sh
 1 #!/bin/sh
 2 DATE=$(date +%Y%m%d)
 3 GENERATE_LIST_TOOL="/usr/local/app/jwtlsb_tools/getConsumeAccount/lib/generateList.sh"
 4 function printHelp()
 5 {
 6     echo "/*****************************************************************/"
 7     echo "[remark]:"输入消费额文件,生成各区1-1011-100101-500501-1000名的号码列表
 8     echo "[usage]:"$0 "INPUT_FILE"
 9     echo "[sample]:"$0 20130320_20130320.list
10     echo "[message]:"$1
11     echo "/*****************************************************************/"
12     exit -1
13 }
14 
15 [ $# -lt 1 ] && printHelp "Wrong Paramters Number!"
16 ${GENERATE_LIST_TOOL} $1 1 10 > ${DATE}_1-10.list
17 ${GENERATE_LIST_TOOL} $1 11 100 > ${DATE}_11-100.list
18 ${GENERATE_LIST_TOOL} $1 101 500 > ${DATE}_101-500.list
19 ${GENERATE_LIST_TOOL} $1 501 1000 > ${DATE}_501-1000.list

  3. 脚本使用

  如果现在需要统计2013年3月20日到2013年3月29日之间的各区消费钱1-10名、11-100名、101-500名、501-1000名的名单,则如下使用脚本即可

  

  

  

posted @ 2013-04-04 15:02  没有113  阅读(468)  评论(0)    收藏  举报