首页 Linux

Linux中对文本分组统计排序

2021-11-01 17:25 知乎-代码狂魔

场景

有时候需要对一些日志进行分组统计排序,比如统计下nginx日志昨天的QPS是多少

原理

分析文本,取出目标信息,可以用cut,在进行分组统计,可以用awk,最后排序,可以用sort

实战

nginx access日志长下面这样

192.168.1.100 - - [13/Jan/2021:00:05:11 +0800] "POST /app/images/logo.png HTTP/1.1" 200 3430 "-" "Jakarta Commons-HttpClient/3.1" "-" "0.106" "0.106"

192.168.1.105:8080"192.168.1.100 - - [13/Jan/2021:00:05:11 +0800] "POST /app/images/logo.png HTTP/1.1" 200 3430 "-" "Jakarta Commons-HttpClient/3.1" "-" "0.106" "0.106" 

分析一下:要统计QPS,只要把时间13/Jan/2021:00:05:11取出来分组统计就可以了

取时间cut

用cut命令,-c20-39意思是从第23取到39,不知道具体是多少就要个测,前面最好加一个head -n 10表示取首10行,否则日志太大终端直接卡死。

head -n 10 access_bak_2021-01-13.log | cut -c20-39

13/Jan/2021:00:05:11

13/Jan/2021:00:05:11

13/Jan/2021:00:05:11

13/Jan/2021:00:05:14

13/Jan/2021:00:05:14

13/Jan/2021:00:05:14

13/Jan/2021:00:05:15

13/Jan/2021:00:05:15

13/Jan/2021:00:05:15

13/Jan/2021:00:05:15

分组统计awk

a[$1]+=1表示对第一列而言,遇到一样的就加一个1,反正对于只有一列的分组统计来说直接加后面这一坨就对了:awk '{a[$1]+=1}END{for (i in a)print i,a[i]}'

head -n 10 access_bak_2021-01-13.log | cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}'

13/Jan/2021:00:05:11 3

13/Jan/2021:00:05:14 3

13/Jan/2021:00:05:15 4

到这里其实统计效果已经出来了

排序sort

sort命令中

-n表示以数值计算,否则sort会认为2比10大,因为2比1大嘛,这是sort的一贯作风

-r表示逆序,不加表示顺序

-k2表示以第2列来排序 当然你也可以写成-nrk2,所以最后就是下面这种效果

head -n 10 access_bak_2021-01-13.log | cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}' | sort -n -r -k2

13/Jan/2021:00:05:15 4

13/Jan/2021:00:05:14 3

13/Jan/2021:00:05:11 3

后记

实际中可能是这样的,后面加个 | more当数据太多的时候使用

cat access_bak_2021-01-13.log | cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}' | sort -n -r -k2 | more

也可能是这样的,最前面加一个grep用于最基本的筛选,比如你的nginx中多个应用或者你仅仅想统计某个path的时候

grep 'app' access_bak_2021-01-13.log | cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}' | sort -n -r -k2 | more

返回首页
返回顶部