在Linux中通常可以使用 grep 和 egrep 命令在文件中筛选字符,查找到你想要的结果。这两个命令的强大之处是可以结合正则表达式使用。那么什么是正则表达式?
正则表达式是一组使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,正则表达式通常分为基本正则表达式和扩展正则表达式。grep命令可以使用基本的正则表达式作筛选,加上一个参数 -E 则可以使用扩展的正则表达式。而egrep则是使用扩展的正则表达式,用法和 grep -E 是一样的。那么现在就来说说正则表达式吧。
一、正则表达式
正则表达式是一类用来匹配字符串的模式,而这种模式最基本的单位是元字符。元字符是在正则表达式中具有某种特殊用途的字符,例如:.、*、?、+、()、[]等等。元字符可以代表其指定范围内的一种模式,各种功能各异的元字符通过正则表达式的规则组合在一起,可以代表几乎任何你所能想到的字符串。元字符按功能分可以分为:字符匹配元字符、次数匹配元字符、位置描定元字符、分组匹配元字符、后向引用元字符等。
不过个人认为在正则表达式中特别需要注意的一点是:1、要分清当前元字符匹配的是单个字符还是一串字符串;2、要知道当前的元字符是修饰当前匹配的字符中的哪一块,前面、后面、括号里、括号内,这一点有点类似于汉语中的主谓宾。
在Linux中grep和egrep分别使用了基本的的正则表达式和扩展的正则表达式,区别是egrep的使用的扩展正则表多了一个+ (匹配其前面的字符至少1次) 和 | (或)以及不用加\转义。
二、grep和egrep的使用
1、grep和egrep支持的正则表达式的元字符有以下这些
(1)、针对单个字符的匹配:
. : 匹配任意单个字符
[]: 匹配指定范围内的任意单个字符
针对[]又有几个扩展的元字符
[0-9]<=>[[:digit:]]:表示匹配所有数字
[a-z]<=>[[:lower:]]:表示匹配所有小写字母
[A-Z]<=>[[:upper:]]:表示匹配所有大写字母
[[:alpha:]]:表示匹配所有字母
[[:alnum:]]:表示匹配所有数字和字符
[[:space:]]:表示匹配所有空白字符
[[:punct:]]:表示匹配所有标点符号
[^]: 匹配指定范围外的任意单个字符
(2)、字符重复匹配:
* : 匹配星号前面的字符任意次,*符号前面接字符,表示匹配前面那个字符零次或多次,只能匹配前面紧挨着的单个字符或分组字符
\? : 匹配问号前面的字符0次或1次
+: 匹配其前面的字符至少1次(此为egrep或 grep -E 专有)
\{m\}: 匹配前面的字符m次
\{m,n\}: 匹配前面的字符m至n次
\{m,\}: 匹配前面的字符至少m次,m次以上
\{0,n\}: 匹配前面的字符至多n次,0不能省略
说明:以上元字符当egrep使用时通通不用加反斜线(\)。
(3)、字符位置锚字匹配:
^: 用于锚定字符串的行首,匹配的字符必须是一行的第一个
$: 用于锚定字符串的行尾,匹配的字符必须是一行的最后一个
\<: 用于锚定词首, 用法和\b加上字符是一样的,放在字符前面
\>: 用于锚定词尾, 用法和\b加上字符是一样的,放在字符后面
(4)、分组匹配:
\(\):括号内的字符为一组,作为一个整体来匹配
|: 或者(此为egrep或 grep -E 专有)
说明:小括号当egrep使用时不用加反斜线(\)。
(5)、后向引用:
\1: 这个必须和分组结合使用才能发挥作用,代表着匹配前面从左往右数第一个括号内匹配到的结果再来一遍,
注意是结果再来遍,表示前后要一模一样,数字代表着前面括号的编号,类似的可以有\2、\3...。
2、元字符总结:
基本正则表达式(grep) | 基本正则表达式(egrep) | 说明 | |
字符匹配元字符 | . | . | 匹配任意单个字符 |
[] | [] | 匹配指定范围内的任意单个字符 | |
[^] | [^] | 匹配指定范围外的任意单个字符 | |
字符重复匹配 | * | * | 匹配星号前面的字符任意次 |
\? | ? | 匹配问号前面的字符0次或1次 | |
+ | 匹配其前面的字符至少1次 | ||
\{m\} | {m} | 匹配前面的字符m次 | |
\{m,n\} | {m,n} | 匹配前面的字符m至n次 | |
\{0,n\} | {0,n} | 匹配前面的字符至多n次 | |
字符位置锚字匹配 | ^ | ^ | 用于锚定字符串的行首 |
$ | $ | 用于锚定字符串的行尾 | |
\< 或 \b | \< 或 \b | 用于锚定词首 | |
\> 或 \b | \> 或 \b | 用于锚定词尾 | |
分组匹配 | \(\) | () | 括号内的字符为一组 |
后向引用 | \1 | \1 | 表示前面从左往右数第1个括号内匹配到的结果再来一遍 |
\2 | \2 | 表示前面从左往右数第2个括号内匹配到的结果再来一遍 | |
... | ... | ||
3、用法
使用前可以先给grep定义一下别名,grep有一个参数:--color=auto,这个参数加上后可以把匹配到的结果按红色显示。。
alias grep='grep --color=auto'
grep常用参数:
-v: 取反匹配,显示不能被模式匹配到的行 -o: 显示被模式匹配到的字串,而非整行 -i: 忽略字符大小写 -E: 支持扩展的正则表达式,和egrep一样 -A: 显示被模式匹配到的行以及下面一行 -B: 显示被模式匹配到的行以及上面一行 -C: 显示被模式匹配到的行以及上下一行
(1)、匹配以Lin开头,以x结尾的字符
说明:.匹配任意单个字符
(2)、匹配单词meritocratic和and之间的任意字符
说明:\<和\>可以放在单词前后定位一个单词,.和*结合代表匹配任意字符任意次
(3)、匹配不是以点号结尾的行
说明:.是元字符所以放在中括号中要使用反斜线(\)转义
(4)、匹配有四位数字的行
说明:[0-9]和[[:digit:]]是一个意思表示匹配任意数字,\{4\}这个表示重复前面模式4次,所以这次有两种写法。
(5)、匹配一行以带有大写字母O且O必须在单词中间的单词开头的行
说明:^代表定位到行首,\<[[:alpha:]]\{1,\}表示匹配任意字母至少一次
(6)、匹配带有一个以数字结尾的单词的行
说明:首先锚定单词的首和尾,然后匹配数字前面的字母至少一次,匹配单词后面的数字一次。
(7)、匹配以标点符号结尾的行
说明:[[:punct:]]$ 这么写也行,参数-v作反向匹配。
(8)、匹配一个以数字结尾的单词
说明:参数-o可以把匹配到的结果显示,而不是整行。
(9)、匹配一个带有以hello开头并且以hello结尾的单词的行
说明:grep加参数-E可以使用扩展正则表达式,所以模式里的括号不用加反斜线了,把hello字符分组
后面使用\1引用前面匹配到的结果。
(10)、|(或)的用法
说明:此处使用的是egrep命令,当使用|时,放在括号里和放括号外是两回事,当不加括号时就如上
面一样,匹配的是以小写sound开头或者带有Sound单词的行。如果要精确匹配以sound或Sound
开头的单词时,就必须这样写了"^(sound|Sound)",如下图:
(11)、最后说一个匹配IP地址的正则表达式
说明:IP地址的格式通常是1.0.0.1-223.255.255.254,我们可以用点号把它分成四段来写,于是就可以这
样写第一段[0-9]匹配数字,但是每段都有一位、两位、三位数并且大于二百的数字最大是223,于
是改进一下,可以这样写[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-2][0-3]为了让 | 自动筛选前后的结果,
我们得给它加上括号使它成为一组,因为之前说过,加括号和不加括号是两个不同的模式,为了让
它锚定字数字可以得到\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-2][0-3])\>,这是第一段,然后可以
匹配第二段的数字,第二段最大是255,于是\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>
三和二是一样的,我们可以直接拿来用(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){2}
第四段也是差不多的,和二、三段类似,\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>
把第一段后面的点号加上,和二三段组合,
\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-2][0-3])\>\.(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){2}
最后把四段全部结合在一起,于是我们就有了最终的结果:
\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-2][0-3])\>\.(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){2}\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>
结语:学习是一个熟能生巧的过程,最好的办法就是学以致用。本人刚学Linux,新手一个,以上是本人的学习
体会,不足之处还望各位大侠批评指正。