Shell 中常见的日志统计方法
实例说明shell 中一些常见的日志统计方法: 查找, 抽取, 统计, 排重统计, 最大值/最小值/平均值统计, 分组统计. 举例一些最基本的日志统计方法.
(1)查看文件
more crawler.log
查看crawler.log日志
tail -n 100 crawler.log
查看crawler.log的最后100行
(2)匹配统计
cat *.log | grep "ERROR" |wc -l
统计在*.log中出现ERROR的行数, 去掉最后一个管道(即: cat *.log | grep "ERROR" )可以查看具体匹配的是哪些行, 大文件不建议这样做.
(3)正则表达式匹配统计
cat *.log | grep ".*Append \(http:\/\/.*\?\) to .*"
查看*.log中匹配正则表达式 .*Append (http:\/\/.*\?) to .* 的行, 为什么括号前要加斜杠呢? 这是shell中正则表达式比较特殊的地方, 括号还有其他个别符号前需要加斜杠.
(4)将匹配正则表达式的内容抽取出来, 排重, 再统计.
比如说一个爬虫日志文件中, 我要统计被抓取网址的数量, 统计的网址不能重复. 已知日志的格式为" Append http://网址 ......." , 同一个网址可能出现多次, 运用上一个统计方法统计出来的是网址出现的总数量, 没有将网址排重, 于是:
cat * |grep "Append" |sed 's/.*Append \(http:\/\/.*\?\) to .*/\1/g'|uniq|wc -l
注意第一个管道grep将符合规则(含有"Append")的行抽出来, 第二个管道sed是shell中家喻户晓的替换命令, 使用方式为 sed 's/正则表达式/替换的内容/g', 我们在正则表达式里使用了分组(就是那个括号), 替换内容里用到了\1代表第一个分组, 如果是第二个则\2,以此类推. 我们先是找到匹配的行,用匹配的第一个分组替换了整行, 这个分组正是我们需要的网址, 因此达到了提取网址的作用. 下一个管道unique是将重复的网址排除, 最后一个管道wc -l是数量统计.
(5)最大数/最小数/平均数统计
基于上一个例子, 如果我们提取的是一个数字, 要进行最大数/最小数/平均数的统计, 需要用到awk管道了, 将wc -l 换成:
awk '{if(min==""){min=max=$1}; if($1>max) {max=$1}; if($1< min) {min=$1}; total+=$1; count+=1} END {print total/count, min, max}'
(6)分组统计
基于第(4)个例子, 如果要统计每个网址出现的次数, 实现类似于mysql group by的效果. 将wc -l 换成:
awk '{a[$1]++}END{for (j in a) print j","a[j]}'
输出格式: 分组,出现的次数
只要掌握以上的基本用法, 可以满足大部分的日常统计需求了, 其中awk的写法基本是固定的, 需要改动的只是正则表达式的部分.