天天看点

文本检索秘技之正则表达式grep和egrep

一、总纲(何为正则)

   所谓正则,又称正则表达式、正规表示法、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。(维基百科如是说)

   为了便于理解,可以将正则想象成为普通语言,普通字符对应的是普通文字,而元字符则对应语法,根据语言的规则,按照语法将文字组合起来,就会表述出你想说的话即想要的文本。

第一式  grep是什么

   grep(global search regular expression(RE)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。UNIX的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符,fgrep就是fixed grep或fast grep,它们把所有的字母都看做单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。

格式:

grep [OPTIONS] PATTERN [FILE...]

grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

第一招:常用选项[OPTIONS]

-v: 反向,显示不能被模式所匹配到的行;

1

2

<code>#检索文件/etc/passwd中非#的行</code>

<code>grep</code> <code>-</code><code>v</code> <code>"#"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/69/wKiom1MGAhzQprWPAAFbfKAMEW8513.jpg" target="_blank"></a>

<a></a>

-o: 仅显示被模式匹配到的字串,而非整行;

<code>#检索/etc/passwd文件中有没有rpcuser用户</code>

<code>grep</code> <code>-o </code><code>"rpcuser"</code> <code>/etc/passwd</code>

-i: 不区分字符大小写, ignore-case

<code>#检索/etc/fstab中包含u中间跟两个任意字符,最后一个字符为d的行,不区分大小写</code>

<code>grep</code> <code>--color -i </code><code>"u..d"</code> <code>/etc/fstab</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/75/wKioL1MII1CCKT1BAAB2w1DiXAM680.jpg" target="_blank"></a>

-E: 支持扩展的正则表达式(加-E可以使用grep启用egrep的功能 grep -E)

-A #:之后的几行字符

<a href="http://s3.51cto.com/wyfs02/M01/12/75/wKiom1MIJD6hNdY8AAEysYx-m6E566.jpg" target="_blank"></a>

-B:之前的几行字符

<a href="http://s3.51cto.com/wyfs02/M01/12/6A/wKiom1MGGYHDxuyPAAD4-1RZy8w076.jpg" target="_blank"></a>

-C #:上下两行

<a href="http://s3.51cto.com/wyfs02/M02/12/6A/wKioL1MGGciRUgr2AAF6Ms16krQ900.jpg" target="_blank"></a>

-n: 显示匹配行及行号,在显示出内容的每行前面会显示行数

第二招:模式(PATTERN)

元字符:不表示字符本身的意义,用于额外功能性的描述

字符匹配:

.: 任意单个字符

<code>#在/etc/passwd文件中检索包含r后面跟两个字符,然后是t的行</code>

<code>grep</code> <code>--color </code><code>"r..t"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/6B/wKioL1MGHRDjyICxAACwNcdVav0597.jpg" target="_blank"></a>

[ ]: 指定范围内的任意单个字符

<code>#在/etc/inittab下检索以S或s后面接任意一个字符,之后是s的行</code>

<code>grep</code> <code>--color </code><code>"[sS].s"</code> <code>/etc/fstab</code>

<code>grep</code> <code>--color </code><code>"jin[[:digit:]]"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/76/wKioL1MIJ9KTydTTAAGa6Ta3qlU023.jpg" target="_blank"></a>

[[:alnum:]] 匹配任何一个字母或数字([A-Za-z0-9])

[[:alpha:]] 匹配任何一个字母([A-Za-z])

[[:lower:]] 匹配任何一个小写字母([a-z])

[[:upper:]] 匹配任何一个大写字母([A-Z])

[[:space:]] 任何一个空白字符:制表符、空格

[[:punct:]] 任何一个标点符号(不包括:[:alnum:]、[:cntrl:]、[:space:]字符集)

[^]:指定范围外的任意单个字符

<code>#在/etc/selinux/config下检索非标点符号开始的行</code>

<code>grep</code> <code>--color </code><code>"^[^[:punct:]].*"</code> <code>/etc/selinux/config</code>

<a href="http://s3.51cto.com/wyfs02/M01/12/6A/wKiom1MGJznwh8wNAAB5pARnz1w901.jpg" target="_blank"></a>

位置锚定:用于指定字符出现的位置

^: 锚定行首

<a href="http://s3.51cto.com/wyfs02/M00/12/77/wKiom1MIRB6Qon9bAAB1MrjnWuE728.jpg" target="_blank"></a>

$: 锚定行尾

<code>以</code><code>bash</code><code>结尾的行</code>

<code>grep</code> <code>--color </code><code>"bash$"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/6A/wKiom1MGKVuitRs3AAGyWw0D4zo774.jpg" target="_blank"></a>

^$: 空白行

<code>#统计/etc/init/tty.conf文件中的空行数</code>

<code>grep</code> <code>"^$"</code> <code>/etc/init/tty</code><code>.conf  |</code><code>wc</code> <code>-l</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/6B/wKioL1MGKi2wli5wAAEmJ5b4Lq8079.jpg" target="_blank"></a>

\&lt;char: 锚定词首,也可以写成\bchar(注:\b是元字符)

<code>#检索/etc/passwd 文件中以r为词首,后面跟两个任意字符,最后一个字符是t的行</code>

<code>grep</code> <code>--color </code><code>"\br..t"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/6A/wKiom1MGKh2wHelkAACGznXgc6I010.jpg" target="_blank"></a>

char\&gt;: 锚定词尾,char\b(注:\b也可以用于锚定词尾)

<code>#以s结尾前面以三个任意字符开头的系统用户</code>

<code>grep</code> <code>--color </code><code>"^...s\b"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/77/wKioL1MIRjPgz-TWAABy8xAhOQY764.jpg" target="_blank"></a>

次数匹配:用来指定匹配其前面的字符的次数

*: 任意次(0次或多次)

<code>#a*b重复a为零次或多次(贪婪模式:尽可能的长的去匹配字符;)</code>

<code>grep</code> <code>--color ab*bd </code><code>test</code><code>.txt</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/73/wKiom1MHfR-A1c7gAABkxGW9RlU963.jpg" target="_blank"></a>

.*: 匹配任意长度的任意字符

<code>#\?: 0次或1次(a\?b 则表示a的匹配一次或一次都没有)</code>

<code>grep</code> <code>--color </code><code>"a\?b"</code> <code>test</code><code>.txt</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/73/wKiom1MHYnjDUxxOAACBPqPITi8355.jpg" target="_blank"></a>

ab*xy:则表示只能匹配*号之前b任意次b(0或多次)

\{m\}: 匹配m次

<a href="http://s3.51cto.com/wyfs02/M01/12/73/wKioL1MHYvDD8fUEAAFM_gQVUrg302.jpg" target="_blank"></a>

\{m,n\}:最少匹配m次,最多匹配n次

<a href="http://s3.51cto.com/wyfs02/M00/12/77/wKioL1MIR-uCBDstAACSatj0rEE334.jpg" target="_blank"></a>

\{m,\}: 至少m次;

\{0,n\}:至多n次;

分组:

\(\)

<code>#检索文件中包含w字符之以es为组后面接t然后任意字符,组es重复一次的行</code>

<code>grep</code> <code>--color </code><code>"w\(es\).*\1"</code> <code>test</code><code>.txt</code>

<a href="http://s3.51cto.com/wyfs02/M01/12/73/wKioL1MHYQbwnjWyAACcBcIrk-E509.jpg" target="_blank"></a>

(es)被作为一个组看待,它是一个组,它的名称是1,然后 .*表示之后的任意个字符,[\1]指代的是前面用括号括起来的es。那么  egrep 里的 w(es)t.*\1 就是说 west后面任意字符,再然后再出现es的,这种行被匹配到

引用:

\1: 后向引用,引用前面的第一个左括号以及与之对应的右括号中的模式所匹配到的内容。(后向引用可以有多次,方法\#(#:数字))

第二式:egrep(grep -E)

为 grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作. 比方说:

- grep 之下不支持 ? 与 + 这两种 modifier, 但 egrep 则可.      

注:

?: 匹配其前面的字符0或1次;

+: 匹配其前面的字符至少1次

|:表示或关系,比如 'gd|good|dog' 表示有gd,good或dog的串

():将部分内容合成一个单元组。比如要搜索 glad 或 good 可以这样 'g(la|oo)d',()的好处是可以对小组使用 + ? * 等。

比如要搜索A和C开头结尾,中间有至少一个(xyz) 的串,可以这样 : 'A(xyz)+C'

- grep 不支持 a|b 或 (abc|xyz) 这类"或一"比对, 但 egrep 则可.  

3

4

<code>#输出包含1或2的行</code>

<code>grep</code> <code>--color </code><code>'\(1\|2\)'</code> <code>/etc/inittab</code>

<code>#或</code>

<code>grep</code> <code>--color -E </code><code>'(1|2)'</code> <code>/etc/inittab</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/74/wKioL1MHciaT6O0iAAEp9pcqeA0598.jpg" target="_blank"></a>

- grep 在处理 {n,m} 时, 需用 \{ 与 \} 处理, 但 egrep 则不需.

诸如此类的... 我个人会建议能用 egrep 就不用 grep 啦..        

第三式:fgrep

不作 RE 处理, 表达式仅作一般字符串处理, 所有 meta 均失去功能.

 ===================================完=========================================

PS:以上是本人学习整理内容,由于能力有限,如有错漏,欢迎各种砖头瓦块.a_c

本文转自 jinlinger 51CTO博客,原文链接:http://blog.51cto.com/essun/1361920,如需转载请自行联系原作者

继续阅读