Shell 中常见的日志统计方法

Stella981
• 阅读 611

前面我发布过"Hadoop兮,杀鸡别用牛刀,python+shell实现一般日志文件的查询、统计", 需要结合python, 可能还是有一定的门槛, 现将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]}'

输出格式: 分组,出现的次数

(7)分组统计排序

上一个例子输出的格式是: 分组,出现的次数. 如果需要在输出的时候按照出现的次数排序, 那么需要在后面加一个管道sort

|sort -t ',' -k 2 -n

其中的参数-t ','表示用逗号分割数据, 结合上面的案例, 将会分成两列, 第一列是网址, 第二列是出现的次数, -k 2 表示第二列参与排序, -n表示把它当成数字来排序, 不加这个参数会出现'10'比'2'小的情况. 如果你要将倒叙拍列输出结果, 可以加参数-r  

只要掌握以上的基本用法, 可以满足大部分的日常统计需求了, 其中awk的写法基本是固定的, 需要改动的只是正则表达式的部分. 里面的每个命令更详细的用法请查阅资料.

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Hadoop兮,杀鸡别用牛刀,python+shell实现一般日志文件的查询、统计
简单的日志统计是不需要使用重量级的Hadoop,我用python实现了日志的统计。原理是用fabric登录到远程linux,组合使用grep、uniq、sort、awk对日志进行操作,可以根据正则表达式指定规则抽取符合规则的日志,做查询,计数,分类统计。注意:要安装fabric(https://www.oschina.net/action/GoToL
Wesley13 Wesley13
3年前
Oracle一张表中实现对一个字段不同值和总值的统计(多个count)
需求:统计WAIT\_ORDER表中的工单总数、未处理工单总数、已完成工单总数、未完成工单总数。表结构:为了举例子方便,WAIT\_ORDER表只有两个字段,分别是ID、STATUS,其中STATUS为工单的状态。1表示未处理,2表示已完成,3表示未完成总数。 SQL:  1.SELECT   2
Stella981 Stella981
3年前
Python计算大文件行数方法及性能比较
如何使用Python快速高效地统计出大文件的总行数,下面是一些实现方法和性能的比较。1.readline读所有行使用readlines方法读取所有行:defreadline_count(file_name):returnlen(open(file_name).readlines())
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这