No.6 Linux文本过滤之grep命令

218 阅读3分钟

前言

可能很多人像我一样,日常生活中经常用到 grep 命令,却不曾想过,grep命令的作用是啥?可能你会想到过滤,这很贴近,实际上,grep命令是一种很强大的文本搜索工具。

对于本人而言,grep常见的场景有两个: 一是过滤进程,这里不再赘述;二是过滤日志,是本文的重点。

测试文件

这里搞了一份测试日志

# app.log

2020-12-26 00:20:22 | INFO | GET /logout | rzflcymjduhtpivgbwea
2020-12-26 00:25:22 | DEBUG | GET /logout | hfkciozaywlbunpdrgsq
2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm
2020-12-26 10:20:22 | ERROR | GET /logout | ilnquztfhcmgyxboksjp
2020-12-27 04:20:22 | INFO | GET /logout | uqdpcvbfnjstxgmzohea
2020-12-27 08:20:22 | DEBUG | GET /login | zknuobcmqlavwsdteypr
2020-12-28 00:20:22 | ERROR | GET /user/info | kqncawjeyobzvlhxtfdp
2020-12-29 00:20:22 | INFO | POST /login | jhmipunxfresbyvlckqg

1.在单个文件中搜索

格式: grep <关键字> 文件名

1.1 查找错误日志

$ grep ERROR app.log
2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm
2020-12-26 10:20:22 | ERROR | GET /logout | ilnquztfhcmgyxboksjp
2020-12-28 00:20:22 | ERROR | GET /user/info | kqncawjeyobzvlhxtfdp

小技巧:一般错误日志远不止这么多,所以可以将错误日志写入一个新文件,便于查看

grep ERROR app.log > error.log

1.2 查找某个接口

$ grep /login app.log
2020-12-27 08:20:22 | DEBUG | GET /login | zknuobcmqlavwsdteypr
2020-12-29 00:20:22 | INFO | POST /login | jhmipunxfresbyvlckqg

补充:除了查找错误日志,特定接口,我还遇到一种情况,就是公司的nginx配置文件非常多,每一个端口代表一个应用,这时就可以通过 grep 端口找到特定应用。

2.在多个文件中搜索

格式: grep <关键字> 文件1 文件2

$ cp app.log app.log.1

$ grep ERROR app.log app.log.1 
app.log:2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm
...(省略)

3.高级搜索

3.1 查找某个时间段

# 精确到分钟 (零点20分到零点29分)
$ grep '2020-12-26 00:2[0-9]' app.log
2020-12-26 00:20:22 | INFO | GET /logout | rzflcymjduhtpivgbwea
2020-12-26 00:25:22 | DEBUG | GET /logout | hfkciozaywlbunpdrgsq


# 精确到小时(3点到9点)
$ grep '2020-12-26 0[3-9]' app.log
2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm


# 精确到天
$ grep '2020-12-2[7-8]' app.log
2020-12-27 04:20:22 | INFO | GET /logout | uqdpcvbfnjstxgmzohea
2020-12-27 08:20:22 | DEBUG | GET /login | zknuobcmqlavwsdteypr
2020-12-28 00:20:22 | ERROR | GET /user/info | kqncawjeyobzvlhxtfdp

补充:网上还有使用 sed -n 命令查询的,格式为:sed -n '/起始时间/,/结束时间/p' 日志文件,但需注意的是起始、结束时间必须在日志文件中存在(如果不存在会导致意外的查询结果)。

$ sed -n '/2020-12-26 00:25:22/,/2020-12-27 04:20:22/p' app.log 
2020-12-26 00:25:22 | DEBUG | GET /logout | hfkciozaywlbunpdrgsq
2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm
2020-12-26 10:20:22 | ERROR | GET /logout | ilnquztfhcmgyxboksjp
2020-12-27 04:20:22 | INFO | GET /logout | uqdpcvbfnjstxgmzohea

3.2 多级查找与运算(同时符合多个条件)
这个其实非常常见,使用管道运算符|即可,比如:

$ grep 'ERROR' app.log | grep 'user/info'        
2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm
2020-12-28 00:20:22 | ERROR | GET /user/info | kqncawjeyobzvlhxtfdp

3.3 多级查找或运算(符合其中一个条件): 这里需要用到正则查找

$ grep -E 'ERROR | /login' app.log 
2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm
2020-12-26 10:20:22 | ERROR | GET /logout | ilnquztfhcmgyxboksjp
2020-12-27 08:20:22 | DEBUG | GET /login | zknuobcmqlavwsdteypr
2020-12-28 00:20:22 | ERROR | GET /user/info | kqncawjeyobzvlhxtfdp
2020-12-29 00:20:22 | INFO | POST /login | jhmipunxfresbyvlckqg

3.4 统计行数:统计行数非常简单,加上-c参数即可

$ grep 'ERROR' app.log -c
3

3.5 显示行号:显示行号也非常简单,加上-n参数即可

$ grep 'ERROR' app.log -n
3:2020-12-26 03:21:22 | ERROR | GET /user/info | pwjulnfezbvxisokrtqm
4:2020-12-26 10:20:22 | ERROR | GET /logout | ilnquztfhcmgyxboksjp
7:2020-12-28 00:20:22 | ERROR | GET /user/info | kqncawjeyobzvlhxtfdp

写在最后

各位老板,创作不易,更需不断地磨练和总结,欢迎关注我,我是言淦,为你分享各种实用的编程知识与编程技巧,你们的点赞与关注是我前进和创作的最大动力!!