Shell 中常见的日志统计方法

ne3g 10年前

实例说明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的写法基本是固定的, 需要改动的只是正则表达式的部分.