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
再编写脚本调用上述脚本分别传递具体参数进行处理。
最终得到的几个脚本如下:
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"
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
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-10,11-100,101-500,501-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名的名单,则如下使用脚本即可