Shell编程入门进阶之Grep命令及正则表达式知识梳理

一、grep,egrep,fgrep命令

 本文中主要介绍了linux系统下grep egrep fgrep命令和正则表达式的基本参数和使用格式、方法。

           为了提高文章阅读性,我约定:

           ★所有基本元字符都不包含右

           ★红色字体表示被匹配的内容(不包括所有).
1.1 基本概念:        

       grep(global search regular expression(RE) and print out theline,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它只能使用基本的正则表达式搜索文本,并把匹配的行打印出来。

       grep是很常见也很常用的命令,它的主要功能是进行字符串数据的比较,然后符合用户需求的字符串打印出来,但是主意,grep在数据中查找一个字符串时,是以“整行”为单位进行数据筛选的。它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件内容。

       egrep命令等同于grep -E,利用此命令可以使用扩展的正则表达式对文本进行搜索,并把符合用户需求的字符串打印出来。

       fgrep命令等同于grep -F,它利用固定的字符串来对文本进行搜索,但不支持正则表达式的引用,所以此命令的执行速度也最快。fgrep就是fixed grep或fastgrep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。此文不作阐述。

1.2 命令基本用法

通过man命令,我们可以查看到grep的基本用法如下:

wKioL1MIYvuxxADiAADEYgW-YDI433.jpg

其中[options]常用的有如下几个:

--color=auto  →高亮,关键字突出颜色显示
-a   →在二进制文件中,以文本文件的方式搜索数据
grep -a 'rc' /etc/inittab
-c →计算找到'搜索字符串'的次数
-n →输出行号
-v →取反,显示不被模式所匹配到的行
-o →仅匹配在模式当中被模式匹配到的字串,而非整行
-i →不区分字符大小写,ignore-case
-E →支持扩展的正则表达式
-A # →显示匹配到的字符那行及后面#行
-B # →显示匹配到的字符那行及前面#行
-C # →显示匹配到的字符那行及前后面#行


二、正则表达式:

2.1 基本概念:

       正则表达使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。简而言之,正则表达式就是处理字符串的方法,以行为单位进行字符串的处理,通过一些特殊符号的辅助,可以让用户轻松搜索/替换某特定的字符串。

       正则表达式分为两类:基本的正则表达式和扩展的正则表达式

2.2 正则表达式详解介绍:

2.2.1 基本的正则表达式

(1)元字符:

.   → 点号,匹配任意单个字符
如grep "r..t" /etc/passwd ,表示匹配r和t中间有两个任意字符的内容。

wKioL1MHWL-hynalAADt8VQUI88610.jpg

[ ]   → 匹配指定范围内的任意单个字符

如grep "[0-9]" /etc/inittab ,表示匹配0到9中任意一个数字。

wKiom1MHWZiyYn-xAAG9ZhVSyjo558.jpg

[^]   → 匹配指定范围外的任意单个字符
如grep "[^0-9]" file ,表示出了数字,都匹配

wKioL1MHWYjSCGCwAADHDKzyhrA781.jpg

(2)次数匹配:

注意:grep默认工作在贪婪模式下,即尽可能长的匹配
*   → 匹配其前面的字符任意次
.*   → 和*组合使用,表示匹配任意字符任意长度(包含0次)。

使用示例:

如有文本a.txt包含内容如下:

wKiom1MHWcHxqXceAAAoNVbgMMM875.jpg

使用 grep "a*b" test1,匹配情况如下:

wKioL1MHWa3DvLIaAABlRaTDF9M460.jpg

使用 grep "a.*b" test1,匹配情况如下:

wKiom1MHWfzRyD1hAABjMzw8HUY034.jpg

其实就是a开头,b结尾的都被匹配上了。

\?   → 匹配其前面的字符1次或0次

使用grep "a\?b" a.txt ,匹配情况如下:

wKioL1MHWe3CtQoTAABoFcCR7YI756.jpg

注意跟 grep "a*b" test1的区别!!

\{m\}  → 匹配其前面的字符m次

\{m,\}  → 匹配其前面的字符至少m次

\{m,n\}匹配其前面的字符至少m次,至多n次

\{0,n\}  → 匹配其前面的字符0至n次

如:\{2,\}  表示匹配至少2次:  

wKiom1MHWimTnENvAABUExnVIHM523.jpg

(3)字符集和:

[:digit:]所有数字[0-9]

[:lower:]所有小写字母[a-z]

[:upper:]所有大写字母[A-Z]

[:punct:] 所有标点符号
[:space:] 表示空格或tab键
[:alpha:] 表示所有字母(包含大小写) [a-zA-Z]

[:alnum:]表示所有字母和数字[0-9a-zA-Z]

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

wKioL1MHWhiBUwUFAACRbyr26iE377.jpg

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

(4)位置、字符锚定:

^ 锚定行首 ,此字符后面的任意内容必须出现在行首

如查找/etc/passwd文件中以root开头的行:

wKioL1MHWi6CDYW7AACA7FLIKpo972.jpg

$锚定行尾 ,此字符前面的任意内容必须出现在行尾

如查找/etc/passwd中以bash结尾的行:

wKiom1MHWySzlSaiAAE-9WCKQq0225.jpg

^$空白行

如统计/etc/rc.d/rc.sysinit文件中有多少空白行:

wKioL1MHWzaTpetbAAB1ozphHrk850.jpg

\<或\b锚定词首 ,其后面的任意字符必须作为单词首部出现
\>或\b锚定词尾 ,其前面的任意字符必须作为单词的尾部出现

\<条件\>或\b条件\b查找某个独立的单词

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

wKiom1MHW-iDsF0mAAC9U7pfljw159.jpg

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

wKioL1MHXH_zpZQbAADWD0QzIxM971.jpg

如锚定一个精确指定的字符:

wKioL1MHXLbTubAQAACHoTihdnc275.jpg

(5)分组:

\(ab\) 表示ab整体作为匹配字符
\(ab\) * → 表示ab整体作为匹配字符,且匹配任意次
\(ab\)\{1,\} 表示ab整体作为匹配字符,且匹配至少一次
分组还可以后向引用
\1 引用第一个左括号以及与之对应的右括号所包括的所有内容

\2引用第二个左括号以及与之对应的右括号所包括的所有内容

\3引用第三个左括号以及与之对应的右括号所包括的所有内容

如test2有文本内容如下:

wKioL1MHXWuglgQ-AABDKgLag1A502.jpg

grep "\(l..e\).*\1r" test2 表示匹配结果如下:

wKiom1MHXerzvHxZAACM27SYJTE690.jpg

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

2.2.2 扩展的正则表达式

       grep -E 表示支持扩展的正则表达式

       grep -E = egrep

       扩展的正则表达只是在基本的正则表达上作出了小小的一点修改,其修改如下:

在扩展的正则表达中把\( \)  写成()、\{ \}  写成{ },另外加入了+:次数匹配,匹配其前面的字符至少出现一次,无上限、|: 或者(二取一),其余的都一样, 基本正则表达式,使用( ) { } . ?  |都需要转义,在扩展正则表达中不需要加\其详细信息如下:

(1)元字符:

       字符匹配的命令和用法与基本正则表达式的用法相同,这里不再重复阐述。

(2)次数匹配

上述字符匹配中,基本正则表达式与扩张表达式完全相同,但次数匹配就有些不一样了。

*匹配前面字符任意次,与基本正则表达式意义相同

?匹配其前字符0次或1次,其前面不需要 \ 转义

+匹配其前字符至少一次,等于基本正则表达式的  \{1, \}

{m}  → 匹配其前面的字符m次,等于基本正则表达式的\{m\}

{m,}  → 匹配其前面的字符至少m次,等于基本正则表达式的\{m,\}

{m,n}匹配其前面的字符至少m次,至多n次,等于基本正则表达式的\{m,n\}

{0,n}  → 匹配其前面的字符0至n次,等于基本正则表达式的\{0,n\}    

(3)字符集和:

       字符集和基本正则与扩展正则通用,在此不在阐述。

(4)位置、字符锚定:

       用法和基本正则表达式的用法相同,在此不再阐述。

(5)分组:

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

(ab) 表示ab整体作为匹配字符,等于基本正则表达式的\(ab\)
(ab) * → 表示ab整体作为匹配字符,且匹配任意次,等于基本正则表达式的\(ab\)*
(ab){1,} 表示ab整体作为匹配字符,且匹配至少一次等于基本正则表达式的\(ab\)\{1,\}
分组还可以后向引用
\1 引用第一个左括号以及与之对应的右括号所包括的所有内容

\2引用第二个左括号以及与之对应的右括号所包括的所有内容

\3引用第三个左括号以及与之对应的右括号所包括的所有内容

egrep "(l..e).*\1r" test2 表示匹配结果如下:

wKioL1MHXhiTICaqAAD5RGGL1YU732.jpg

除了方便后面引用外,分组还非常方便的可以使用上述次数匹配方法进行匹配具有相同条件的数据。

如:egrep '^(halt).*\1' /etc/passwd 搜索/etc/passwd中以halt开头,而后面还存在halt的行

wKiom1MHXomzvnsgAACHV6GUuuY086.jpg

(6)或者:

|表示或,如

a|b 表示匹配a或者b

B|bike 匹配B或bike,即 | 匹配的是其整个左边或者右边

wKiom1MIS_vQwwknAADH_Q1MuEs332.jpg

(B|b)ike 匹配Bike或者bike,注意与上一行的区别

wKioL1MITByxRF5EAABuLp6BJas246.jpg


三、grep,egrep应用小示例:

3.1 显示~/.bashrc 中以#开头,且后面跟一个或者多个空白符,而后又跟了任意非空白符的行;

wKiom1MITU7yQk4tAAGRBSx0ZjI724.jpg

3.2 显示/proc/meminfo文件中以大小写s开头的行;

wKioL1MITZLylPpCAAD_yYW6EUY438.jpg

或者:

wKioL1MIabbRsxB8AAELPQRU6sU291.jpg

3.3 取出默认shell为非bash的用户;

wKiom1MIaiaSvd6NAAB4CSGrKCQ315.jpg

3.4 取出默认shellbash的且其ID号最大的用户;

wKioL1MIap6DLkWhAACmmGRKQis896.jpg

3.5 找出/etc/passwd文件中一位数或两位数;

wKioL1MIa-rxflTHAAI6z4ITFQ0826.jpg

3.6 找出ifconfig命令结果中的1255之间的整数;

wKioL1MIbWLihvh1AAKqtkmcp8E738.jpg

3.7 查看当前系统上root用户的所有信息;

wKioL1MIbpHSCBDwAACB4DHRFxY814.jpg

3.8 添加用户bashtestbashbasher,而后找出当前系统上其用户名和默认shell相同的用户;

wKiom1MIbtWgl2YQAAJtmfqNqsw518.jpg

3.9 写一个模式,能匹配真正意义上的IP地址;(1.0.0.1--223.255.255.254

wKiom1MIb_aSEGO1AAHX9UsZjr8382.jpg



Ps:如果本文章对你学习有所帮助,那将是我最大的荣幸;

若文章中出现任何问题,烦请指出或联系我(QQ:2399447849)

Thanks!



本文出自 “一叶知秋” 博客,转载请与作者联系!

你可能感兴趣的:(正则表达式,grep,egrep)