grep 正则表达式

grep 转义字符“\” 查找,因为“\”grep 命令里是转义字符,所以需要特殊的处理,



比如要查找#include “....\mydir\test.h” 中的”"



grep “\\” test file 其中,前两个“\” —>\转义本身“\”,后面两个”\“才是要查找的“\”;



或者



grep \\ test file 其中,前两个“\” —>\转义本身“\”,后面两个”\“才是要查找的“\”;



或者



grep ‘\’ test file,其中,前一个是转义符号,后面一个是查找的“\”



测试查找$:



grep ‘$’ test.sh 实际传入grep的是$



grep “\$” test.sh 实际传入grep的是$



grep \$ test.sh 实际传入grep的是$



查找”有效:



grep ‘”’ test.sh 实际传入grep的是”



grep ‘"’ test.sh 实际传入grep的是"



grep “"” test.sh 实际传入grep的是”



查找\有效:



grep “\\” test.sh 实际传入grep的是\



grep ‘\’ test.sh 实际传入grep的是\



其他特殊字符的转义



1、Tab匹配



$'\t'


2、空格



转义符+空格



3、括号



转义符+括号



4、精确匹配



\<匹配内容\>(以**开头,以**结尾)


转义的说明:



meta是元语言的意思,即当前命令作用域下的特殊含义字符,包括空格,$,’,”,\等等,主要是区分为命令meta和shellmeta,而且在不同的命令作用域下meta是不同的。



针对shell命令行作用域下:



无引号将先处理所有shell的meta。



单引号为硬转义,shell的meta在内部应无效。



双引号为软转义,大部分shellmeta无效,但$,\,`不会失效。



下面先给出博主试验后得出的结论:



多层转义原理:在命令中使用引号例如grep时,它的转义有两层,一层是shell本身的mate,这一层可以用echo命令测试输出,经过这一层转义之后的结果会进入grep命令,并在grep中进行第二层的转义,例如当grep利用双引号查找$时要将转义字符作为第二层转义的输入送到grep中,grep实际输入的应该是$,这样才能查找到文件中的$字符,对于grep来说他的meta我暂时只发现了$和\,$对于grep来说有进行变量转换的内部功能,\在grep内还是转义功能,而”和’并不是grep的meta,因此不需要二层转义,是否需要二层转义应该是根据不同命令的meta决定的。



grep
目录
grep扩展正则表达式(egrep)
基本正则表达式
最常用的几个选项:
-i:不区分大小写搜索
–color: 关键字突出颜色显示
-v: 显示没有被模式匹配到的行
-o:只显示被模式匹配到的字符串
-E: 扩展正则表达式,即egrep
-A 10,-B 10: 显示匹配行的前面、后面10行
基本元字符
. 点号,匹配任意单个字符,如grep “r..t” /etc/passwd ,表示匹配r和t中间有两个任意字符的内容。
[] 匹配指定范围内的任意单个字符,如grep “[0-9]” /etc/inittab ,表示匹配0到9中任意一个数字
[^] 匹配指定范围外的任意单个字符,如grep “[^0-9]” file,表示出了数字,都匹配
次数匹配
注意:grep默认工作在贪婪模式下,即尽可能长的匹配



  • 匹配其前面的字符任意次,如:grep “a.b” test1匹配所有a开头、b结尾的字符串
    .
    .和*组合使用,表示匹配任意字符任意长度(包含0次)。
    \? 匹配其前面的字符1次或0次,使用grep “a\?b” test1,匹配b,ab
    {m,n} 匹配其前面的字符至少m次,至多n次,如:{2,}表示匹配至少2次,grep “a{2,}” test1匹配aab;如:{0,3} 匹配0至三次
    字符集合
    [:digit:] 所有数字 [0-9]
    [:lower:] 所有小写字母 [a-z]
    [:upper:] 所有大写字母 [A-Z]
    [:punct:] 所有标点符号
    [:space:] 表示空格或tab键
    [:alpha:] 表示所有字母(包含大小写) [a-zA-Z]
    [:alnum:] 表示所有字母和数字 [0-9a-zA-Z]
    1
    2
    3
    4
    5

    如匹配/etc/resolv.conf中的所有数字:


    grep “[[:digit:]]” /etc/resolv.conf


    需要注意的是,这里需要用额外的 [] 将字符合集括起来。


    nameserver 192.168.18.210
    nameserver 8.8.8.8
    位置锚定
    ^ 锚定行首,此字符后面的任意内容必须出现在行首,如查找/etc/passwd文件中以root开头的行:grep “^root” /etc/passwd
    ( 锚定行尾,此字符前面的任意内容必须出现在行尾,如查找/etc/passwd中以bash结尾的行:grep “bash)” /etc/passwd
    ^( 空白行,如统计/etc/php.ini文件中有多少空白行:grep “^)” /etc/php.ini |wc -l
    <或\b 锚定词首,其后面的任意字符必须作为单词首部出现
    >或\b: 锚定词尾,其前面的任意字符必须作为单词的尾部出现
    <条件>或\b条件\b:查找某个独立的单词
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12


    如查找/etc/passwd文件中以r开头,t结尾,中间包含两个任意字符的单词


    grep “<r..t>” /etc/passwd





root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin



注意与grep “r..t” /etc/passwd结果的区别:


grep “r..t” /etc/passwd



root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
grep的分组
() 分组
(ab) 表示ab整体作为匹配字符
(ab)* 表示ab整体作为匹配字符,且匹配任意次
(ab){1,} 表示ab整体作为匹配字符,且匹配至少一次
分组还可以后向引用
\1 引用第一个左括号以及与之对应的右括号所包括的所有内容
\2 引用第一个左括号以及与之对应的右括号所包括的所有内容
\3 引用第一个左括号以及与之对应的右括号所包括的所有内容
1
2
3
4
5
6
7
8
9


如test2有文本内容如下:


He love his lover.
She like her liker.
He like his lover.



grep “(l..e).*\1r” test2


匹配结果如下:


He love his lover.
She like her liker.
即引用的为前面匹配内容加上r,因此He like his lover这一行就不会被匹配。



字符匹配
扩展模式下的字符匹配与基本正则表达式的字符匹配相同,如:



. 表示任意单个字符
[] 表示范围内人任意单个字符,如[0-9],表示任意单个数字
[^] 表示范围外的任意单个字符,如[^0-9],表示出数字外的任意单个字符
次数匹配
上述字符匹配中,基本正则表达式与扩张表达式完全相同,但次数匹配就有些不一样了。




  • 匹配前面字符任意次,与基本正则表达式意义相同
    ? 匹配其前字符0次或1次,其前面不需要 \ 转义

  • 匹配其前字符至少一次,等于基本正则表达式的{1, } ?+ = *
    {m,n} 匹配其前字符至少m次,最多n次,等于基本正则表达式的{m,n}
    位置锚定
    与基本正则表达式完全意义,请参考上一篇。



分组
基本正则表达式中支持分组,而在扩展正则表达式中,分组的功能更加强大,也可以说才是真正的分组,用法如下:



() 分组,后面可以使用\1 \2 \3…引用前面的分组
除了方便后面引用外,分组还非常方便的可以使用上述次数匹配方法进行匹配具有相同条件的数据。
如:grep ‘^(barlow).*\1’ /etc/passwd 搜索/etc/passwd中以barlow开头,而后面还存在barlow的行



或者
| 表示或,如a|b表示匹配a或者b,B|barlow匹配B或barlow,即 | 匹配的是其整个左边或者右边
(B|b)arlow 匹配Barlow或者barlow
使用范例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33


a|b:匹配a或b


grep -E “Barlow|barlow” barlow1.txt



(B|b)arlow 匹配Barlow或者barlow


grep -E “(B|b)arlow” barlow1.txt



获取以A,B,C表的插入数据行


cat < a.txt «EOF
INSERT INTO A VALUES …
INSERT INTO B VALUES …
INSERT INTO C VALUES …
#INSERT INTO D VALUES …
EOF
cat a.txt |grep -E “^INSERT INTO `(A|B|C)` “



找出/etc/fstab文件中以#开始的行,并标识其所在行号


grep –color -n -E “^[#]+” /etc/fstab
2:#
3:# /etc/fstab
4:# Created by anaconda on Sat Jul 13 18:13:39 2013



找出除lo以外的其他接口的IPv4地址信息


ip add list |egrep “^[[:space:]]+inet[^6].*[^lo]$”



inet 192.168.7.100/24 brd 192.168.7.255 scope global eth0



找出ifconfig不包含回环地址的其他IP地址,不包括IP广播地址和子网掩码等信息:


ifconfig |egrep –color “<([1-9]|[1-9][0-9]|1[0-1]+[0-9]+|12[^7]+|1[3-9]+[0-9]|2[01][0-9]|22[0-3])>(.<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])>){2}.<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])>”



inet addr:192.168.7.100 Bcast:192.168.7.255 Mask:255.255.255.0



多条件并列排除匹配


zcat mydb.bak.20140408_1.dump.gz |grep -v -E “^INSERT INTO `(ci_channel|ci_cluster)` “



Category linux