
假设有一个文件(或一堆文件),并且想要在某些文件中搜索特定的字符串或配置关键字。Windows下,你可能会打开此类文件用搜索框(CTRL+F)输入关键字点搜索,这很麻烦并且还不能随心所欲的搜。在Linux就不同了,我们可以用Grep什么是shell,可以用正则式子随心所欲的搜,不仅可以搜一个文件,还可以搜一堆文件。搜索的入口跟出口可以对接上管线,搜索别的工具的结构或则把搜索结果传递给其他工具用。

今天我们就来讲Linux Shell下的文本处理三剑客之Grep。为了了解其用法最简便方式是使用系统帮助跟man:
grep -h

man grep

其中man的比较详尽,来自于其帮助指南,在linux(centos为例)下查询外置命令帮助指南的方式是用rpm -qd grep
-q表示查询;-d表示列举其文档(document):
rpm -qd grep

grep基础
在开始之前,我们以centos自带的词典文件为范本,该文件坐落/usr/share/dict/words
wc /usr/share/dict/words
479829 479829 4953699 /usr/share/dict/words
文件包含48万个词汇,一行一个词汇,由centos的word包提供。grep 也有一个-c(--count)选项对搜索匹配的行进行统计,我们先来用他来统计下它的词汇树
grep --count '.' /usr/share/dict/words
479829
![]()
这跟wc的结果一样。
搜索中我们制订了方式为".",表示搜索包含起码一个字符,空格,空格,制表符等的行。
grep正则式子基础
grep最重要两个特点:一个是搜索相当快,一个是支持正则式子(RE,regexes)。正则式子使grep显得更强大。所以我们首先要介绍下正则式子基础。
开头
假设我们想搜以C开头词汇,我们还要要使用正则方式的开头方式:(^)加一个开头字符。比如:

结尾
要搜索以特定字符结尾的方式,使用符号($)表示字符串的结尾。比如要搜索以sth结尾的短语
grep 'sth$' /usr/share/dict/words

其他RE方式
正则式子时态很复杂,而且各个系统或许略有差别,具体还要参考对应文档,grep中常用的句型也有:
.表示单个字符
* 表示其之前字符出现0次或则多次,比如.*表示任意字符。
+ 表示其之前字符出现1个或则多个。注意这个只在加强的egrep或则grep -E下可用。基本grep下要用\+
? 表示其之前字符出现0个或则一个。基本grep下要用\?
{}表示之前字符出现的次数限定,比如:{n} n次,{n,m}n至m次,{n,}至少n次,{0,m}最多m次。grep下要用\{n\}

[a-z] [0-9] 表示a~z,0~9的范围。
[^]取反,表示匹配不仅范围此外的方式。
\<, \b: 词首,\>, \b:词尾。
() 表示分组。基本grep下要用\(\)。
|表示逻辑或,匹配多个式子的任何一个。基本grep下要用\|
清除注释(-v)
前面初窥grep的学问,我们接着以一些例子来说明写grep的详细应用。我们晓得在linux下这些配置文件都包含了大量的注释(#开头的行),解释太详细,但是通常我们不愿去仔细了解,所以希望浏览时侯清除掉。我们以ntp.conf为例:
cat /etc/ntp.conf

grep 的-v选项表示排除机制,表示显示所有不匹配的内容,比如要除去ntp.conf中的注释我们使用:
grep -v '^#' /etc/ntp.conf

上面所有注释行都用空行了,显示清晰了一点,但是看着也有点恼火,不是吗?
那我们就想办法除去空行,方法也简略就是用管线对接至另一个grep,再去掉掉空行($)
grep -v '^#' /etc/ntp.conf |grep -v '^$'

OK什么是shell,这下清新多了。
仅输出/et /passwd用户名(-o)

为了演示grep的功能跟正则式子的用法,我们还要解读/etc/passwd文件并仅复印用户名。
cat /etc/passwd

文件中各行的数组详细涵义:
<name用户名>:<明码密码,现在都为x表示在shadow加密保存>:<UID>:<GID>:<GECOS用户备注信息>:<用户目录>:<shell>
为了仅输出用户名,可以使用如下查询
grep -o '^[a-zA-Z_-]\+' /etc/passwd

在前面的grep命令中,我们使用了grep -o(--only-matching)选项,表示仅显示匹配<PATTERN>的行那部份。
显示临近行(-C,-A,-B)
我们在查看日志时侯,有时不能只看匹配的行,而须要上下文信息。grep也提供了这么的功能,显示匹配行之前或则以后的行。这在故障清查过程中特别有用,你再也不需要打开文章,定位,然后再看上下文了。
-C n 表示复印匹配行及前后n行的信息。此处-C可以省略,用-n
-A n表示复印匹配行及以后n行的信息。
-B n表示复印匹配行及之前n行的信息。
比如我们搜索tomcat catalina.out日志中的严重错误,可以用:
grep 'SEVERE: Error' catalina.out

由于缺少上下文,具体信息难以获取。这时候就可以使用-C
![]()
grep -20 'SEVERE: Error' catalina.out
这样可以获取完成错误信息进行错误定位:

搜索二进制文件(-a)
grep 是一个文本三剑客之一,但是文本剑客并不意味着他就只好处理文本文件了。实际上对二进制文件只是可以的。这就是grep的-a(--binary-files=text)选项,可以对二进制的文本进行搜索跟显示。这在安全领域很有用,比如有时候还要对这些文件判定是否有害,是否有木马,可以简略用grep搜索其特性即可。我们举个实例例如,对一个java class文件x.class,我们用javap解读这个类文件
javap x.class

我们用grep –a查看:
grep -a '.' x.class

有World,我们用他做关键字搜索
grep -ia 'world' x.class
就能搜至结果:
ello World,..
java/lang/Objectjava/lang/SystemoutLjava/io/PrintStream;java/io/PrintStreamprintln(Ljava/lang/String;)
注意后面用了-i选项,表示忽视大小写,也是常用的grep选项之一。
总结
本文我们介绍了Linux下的shell三剑客之一,文本搜索利器grep,希望能对你们有所帮助。其他两个剑客是流式文本处理工具sed 和awk语言,以后有机会我们再做介绍。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-135048-1.html
将来IBM业务萎缩裁员要赔款吗