0924 介绍一个既常见又强大的linux指令给大家——grep指令

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_30531261/article/details/82827190

引言

工作中,经常要查看程序的日志,最简单粗暴的方式就是使用工具xftp5。把日志文件拉到本地,然后用文本编辑器如nodepad++进行查看。在刚进公司的时候,每次要查看日志,都是使用这种方式。

但是,在与其他项目经理接触的过程中,我发现使用linux指令在命令行中直接查看日志是一个更好的选择。首先,逼格更高,其次,效率更高。

如果能很好的使用grep命令,效率真的会很高。

效率更高,怎么说?

举个例子

举个例子,假如我要查看最近几次的BusinessException,那么我可以通过xftp5下载最新的那份日志文件,拉到本地,然后通过文本编辑器,拉到最后一行,在搜索框中输入关键字“BusinessException”然后向前搜索。如此查看最近几次的BusinessException。这还可以忍受。

再举一个例子,假如我要查看昨天发生过的所有的BusinessException(ps:日志文件按照日期划分,并且每30m又划分为1个小的文件,而通常一天下来,假设日志文件一共300MB),那么就有10段日志文件。如果这时要查看这一天发生过的BusinessException,那么就得把这10份日志文件下载下来,然后一个一个文件的去遍历,再个每个具体的文件中去搜索。这样依然可行,只是效率会很低很低。其实一开始我也是使用这种方式,偶尔一两次还能接受,但是一天四五次,七八次我就无法忍受了,时间都花在了查日志上,不是在浪费时间吗???

而其实使用grep指令,一行语句解决上面的问题。

真实例子

上面说的例子可能你会觉得只是为了说明问题无中生有的一个操作。然而在工作中,还真的是有类似的操作。譬如,用户向客服反馈说自己上星期5在操作app的时候绑卡一直失败,提示说“绑卡失败,请稍后重试”。这时你就得查看日志排查问题了。就像前面说的,一天下来,日志文件共几百M甚至更多,以30M来分割,那么一天的日志文件就有十几份。如果这时还使用文本编辑器notepad++去定位就会显得很被动了。比方说,你得去问清楚,用户是在什么时候操作发生这个问题的。客户如果说:“用户反馈是在上星期5上午,具体时间他记不太清了”。那么这个时候,你就不得不去查看时间截至至上午的每一份日志文件,然后再一份一份的通过正则表达式加关键字如“userId=13246800000.*?绑卡失败,请稍后重试”(假设用户的账号是13246800000)去搜索。如果你查完时间在上午的每一份日志文件,依然没有定位有问题。你可能会生气会抱怨:“用户是在耍我们吗??”但是如果你要确认用户是否在耍你,你还得把上午除外的其他日志都检查过并且确认确实没找到,你才能确定是用户记错了时间。你还可能会抱怨:“为什么当时出问题的时候不来反馈,而要等隔了几天才来反馈问题?要是一出现这个问题就马上反馈,那我只要查看最新的日志文件,一下就能定位问题了”。然而这种抱怨并没什么用,也不切实际。

好吧,以上说的就是我,一个真实的例子之一!!!之一!!!

如果使用grep指令,会有多简单呢?grep指令支持多文件搜索!grep指令可以把上面我手动的许多操作交给机器,让机器来完成。比如我只要使用这么一个指令,就能找到用户说的“绑卡失败,请稍后重试”的日志:

这里上星期5指的是2018-09-21号。
这一天的日志文件名有如:

theLog.2018-09-21.0.log、
theLog.2018-09-21.1.log、
theLog.2018-09-21.2.log
... 
theLog.2018-09-21.15.log

grep指令为:

grep -a -r -E 'userId=13246800000.*?绑卡失败,请稍后重试' ./theLog.2018-09-21*

这样就能匹配出以theLog.2018-09-21开头的文件名且满足正则表达式"userId=13246800000.*?绑卡失败,请稍后重试"的关键字所在的那一行的信息。

如果查询出来的结果为空,说明这一天这个用户都没出现过这个绑卡失败的问题。这时我们就可以怀疑是用户记错的日期,然而我们并不需要被动的找客服,让客服询问用户操作的日期到底是哪一天,毕竟用户可能真的记不起了,他只记得是上星期,也可能是上上星期。这时我们只要简单的改变一下grep指令中的日期:

grep -a -r -E 'userId=13246800000.*?绑卡失败,请稍后重试' ./theLog.2018-09-22*

或者

grep -a -r -E 'userId=13246800000.*?绑卡失败,请稍后重试' ./theLog.2018-09-20*

就能一下子查找用户在20号和22号有没有出现过这个问题。如果依然查不到,可以更粗暴的查询9月份的所有日志文件:

grep -a -r -E 'userId=13246800000.*?绑卡失败,请稍后重试' ./theLog.2018-09*

而grep指令的效率非常非常的高,在使用notepad++对单独的一个文件进行搜索时,经常会出现卡顿,而使用grep指令,则完全没感觉,一下子就查找完毕了。

最后

grep指令我常用到的参数有 -a,-r,-E,-F,-B,-A,-C,-v。

-a 表示不要忽略2进制数据,每次使用grep指令,都会带上这个参数:

例子:
grep -a '绑卡失败,请稍后重试' ./theLog.log

-r 表示对目录也进行遍历,如果没加-r,当查询范围是目录时,会返回xx Is a directory:

例子(查询范围是当前目录):
grep -a -r '绑卡失败,请稍后重试' ./

-E 表示关键字中使用正则表达式

例子(关键字中使用正则表达式,关键字信息为:userId=1324680开头,且包含绑卡失败,请稍后重试):
grep -a -E 'userId=132480.*?绑卡失败,请稍后重试'

-F 与-E相反,表示关键字中不使用正则表达式

例子(打印含有8个星号的记录,这里的星号不是正则表达式中的星号,它仅仅表示星号):
grep -a  -F '********' ./theLog.log

-B 的B表示before,用法如 -B 1,表示打印关键字所在行以及该行的前一行

例子:
grep -a -r -B 1 '绑卡失败' ./theLog.log

-A 的A表示after,用法如 - A 3,表示打印关键字所在行以及该行的后面三行

例子:
grep -a -r -A 3 '绑卡失败' ./theLog.log
例子(-B和-A一起用):
grep -a- r -B 3 -A 1 '绑卡失败'  ./theLog.log

-C 的单词含义不知道是什么,但是其作用类似上面两个,用法如 -C 1,表示打印关键字所在行以及前后各一行。

例子:
grep -a -r -C 10 '绑卡失败' ./theLog.log

-v 的v表示invert-match,表示反转查询,即打印不含指定关键字的所在行。

例子(匹配不含关键字“====”的记录):
grep -a -r -v  '====' ./theLog.log

grep指令真的很强大,这里不深入的去介绍,只是通过例子介绍一下,让大家知道这个命令,也建议大家尝试着去用指令查询替代文本编辑器查询。当然,要想让grep指令更好的发挥作用,程序的日志记录很重要,如果程序日志都做得太烂,那即使使用grep指令,也不会有过大的作用。

最后的最后,我建议学习linux指令,第一步先是去明白该指令名字的全称,这样才能更好的记住该指令。

如grep,是global search regular expression and print out the line,这样就能很直观的明白grep指令的作用:全面搜索正则表达式并打印出所在行。

又如lsof指令,一开始我总是记成losf,但是知道该指令的全称后,就不会再混淆了。lsof:list open file。即ls是list的缩写,o是open的缩写,f是file的缩写。这样一来,一旦想不起该指令,想想其含义,其单词,自然也就知道是lsof而不是losf了。

哈哈,这是一个过来人的学习建议。希望能帮到有需要的人。

猜你喜欢

转载自blog.csdn.net/weixin_30531261/article/details/82827190