grep全称为:global search regular expression(RE) and print out the line
功能:根据用户指定的模式对目标文件进行搜索,并显示出匹配到字符的行
除了grep还有egrep和fgrep,都有各自的特点
grep 支持基本的正则表达式
egrep 支持扩展的正则表达式,相当于grep -E
fgrep 不支持正则表达式,都视为普通的字符,但速度很快
语法:grep [OPTION]... PATTERN [FILE]...
常用选项:
-v 反向匹配,显示不能被模式匹配到的行
-o 仅显示被模式匹配到的字符串而非整行
-i 不区分大小写
-E 支持扩展的正则表达式,相当于使用egrep
-A# 显示被匹配到的行之后还显示下面的n行 A:after
-B# 显示被匹配到的行后还显示上面的n行 B:before
-C# 显示被匹配到的行后还显示前后n行 C:context
-e 实现多个选项间的逻辑or关系
-w 匹配整个单词
-q 静默模式,无论匹配成功或失败都不会显示信息
--color=auto 被匹配到的字符串以颜色显示
示例:
首先创建一个测试文件,文件名为grep,文本内容如下:
1、取出grep文件中的test字符串
默认情况grep是区分大小写的,所以TEST字符串没有被匹配到
2、取出grep文件中的test字符串并且包括大写
3、取出grep文件中的test字符串包括大写,并显示字符串所在的行号
4、取出grep文件中的test字符串包括大写,并显示符合条件的总行数
使用“-c”选项可以统计出符合条件的总行数,不会显示出每行
5、取出字符串abc,只显示字符串本身,而不是显示字符串所在的整行
注:-o 选项会把匹配到的每个关键词单独在一行显示,此例中第一行的字符串“abc123abc”是分为两行显示
6、取出/etc/passwd文件中包含shutdown字符串的行,并且显示出该行后面的3行
"-A 3" 选项表示同时显示被匹配到的行和该行后面的3行
7、取出/etc/passwd文件中包含shutdown字符串的行,并且显示出该行前面的3行
8、取出/etc/passwd文件中包含shutdown字符串的行,并且显示出该行的前后3行
注:这里是大写的C
9、取出上面例子中的abc单词,而不是字符串
abc包含于某个字符串中不会被匹配,只有作为独立的单词才会被匹配到,-w表示单词,搜索的字符串只有单独存在的时候才会匹配
10、查找grep文本中不包含abc的行
11、匹配出grep文本中test和abc所在的行
-e 选项可以同时匹配多个字符串,多个字符串间存在或的关系,即匹配其中任意一个都算成功
12、匹配grep文本中abc字符串但不显示出结果
-q 选项表示为静默模式,即不管匹配成功或失败都不显示任何信息,可以配合echo $? 查看命令的执行状态,0为成功,非0都为失败,只关心命令是否匹配成功,而不关心内容的时候可以使用这个选项
以上的示例都没有使用正则表达式,当grep和正则表达式结合威力才强大,结合时grep会根据正则的含义查找文本中符合条件的字符串。
什么是正则表达式?
正则表达式,又称规则表达式,计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
^ 锚定行首
$ 锚定行尾
^$ 匹配空行,这里所描述的空行表示“回车”,而空格或tab等都不能算作此处所描述的空行
\< 锚定词首,或写成\b
\> 锚定词尾 ,或写成\b
\B 匹配非单词边界,与\b正好相反
方便示例创建一个测试文件reg,内容如下:
位置匹配:
1、搜索reg文件以abc开头的行
2、搜索reg文件以abc结尾的行
3、精确匹配hello
^hello$ 表示hello既在行首也在行尾,就是整行中只有一个hello
4、匹配reg文件中的空行
^$表示行尾相连,换句话说就是空行,可以看到reg文件中有两行“空行”,-n选项表示打印出行号
5、搜索出hello为词首的行
相反hello\> 表示hello作为词尾才会被匹配
6、匹配hello单词
\<hello\> 表示hello既是词首也是词尾才会被匹配,换句话说只有hello作为独立的单词则会被匹配。\b \b和\< \>等价
和\b相似的还有一个\B, \B用来匹配非单词边界的,效果和\b相反的
次数匹配:
创建一个测试文件,内容如下:
1、查找regex文本中连续的4个d字符所在的行
使用grep "dddd" 虽然也行,但如果是100个呢? \{m\}表示匹配前面个字符m次,必须为连续字符中间不能有空格
如果字符连续出现的次数大于指定的次数,也能被匹配到,示例如下:
指定的匹配2次,第4行被匹配到了,同时第5行也被匹配到,因为第5行中b字符出现了3次,包含2次,所以前面两个连续的b被匹配到了。
如果不想出现上述情况,只想精确匹配出现2次的字母b,可以使用词首词尾锚定\<\>,示例如下:
2、匹配regex文本中连续出现至少2次至多4次的字符
如上图所示,连续出现2次,3次,4次的字母d都被匹配到了
3、匹配regex文本中o字符连续出现次数至少2次,上不封顶
如上图所示,只要o字符连续出现次数大于2次即可被匹配
再延伸下\{,2\} 表示什么意思呢?
\{,2\} 表示之前的字符连续出现次数至多2次,最小次数为0次,前面的字符也可以不出现(所以ab也被匹配了),即可被匹配.
注:这里是匹配前面字符c最多2次,而不是字符串abc ,容易搞晕。
正则符号 *
正则的 * 不要和通配符的 * 搞混淆了,通配符表示匹配任意长度任意字符,正则表达式里的*代表另一个意思,在正则表达式中*表示匹配前一个字符0次或多次,示例如下:
d* 表示d连续出现任意次即被匹配,为什么其他行也被打印出来了,因为*表示任意次,包括0次,相当于d连续出现了0次,所以被输出了。
正则表达式中"." 表示任意单个字符,示例如下:
"ee."表示ee后面跟任意单个字符都会被匹配
"ee.."表示ee后面跟任意两个字符,都会被匹配到
再回过头来理解".*"就容易多了,".*"在正则表达式中表示任意长度的任意字符,正则表达式中的".*" 与通配符的"*" 是一个意思
正则表达式中的"\? 与 \+"
\? 表示匹配其前面的字符0次或1次
\+ 表示匹配其前面的字符至少1次
示例:
"c\?"表示c出现0次或1次,都会被匹配,所以ab,abc都被匹配到了,ab被匹配是因为c出现了0次
"c\+" 表示c至少要出现1次,则都会被匹配
正则表达式中的分组"\(\)"
上述示例中\{2\}表示前面个字符连续2次即被匹配到,但影响的只是单个字符o, 如果要匹配出上面连续两次出现的hello字符串则可以使用分组
示例:
分组\(hello\)则把hello视为一个整体
分组还可以嵌套使用。示例:
后向引用: