原创文章,欢迎转载。转载请注明:转载自 祥的博客
原文链接:https://cloud.tencent.com/developer/article/1596388
- @[toc]1.正则表达式1.1.基本正则表达式1.2. POSIX字符类正则表达式1.3. 元字符正则表达式2.运用2.1.例子2.2.处理特殊字符grep命令3.1.介绍和简单使用3.2. 正则表达式元字符3.3. grep 选项3.4. grep测试实例3.4.1. 普通用法3.4.2. 正则表达式 的基本组成部分
可以看以前的博客[Regex]Get正则表达式:https://blog.csdn.net/humanking7/article/details/51175937
正则表达式 | 描 述 | 示 例 |
|---|---|---|
^ | 行起始标记 | ^tux 匹配以tux起始的行 |
$ | 行尾标记 | tux$ 匹配以tux结尾的行 |
. | 匹配任意一个字符 | Hack. 匹配Hackl和Hacki,但是不能匹配Hackl2和Hackil,它只能匹配单个字符 |
[] | 匹配包含在 字符 之中的任意一个字符 | cookl 匹配cook或cool |
^ | 匹配除 ^字符 之外的任意一个字符 | 9^01 匹配92、93,但是不匹配91或90 |
- | 匹配 [] 中指定范围内的任意一个字符 | 1-5 匹配从1~5的任意一个数字 |
? | 匹配之前的项1次或0次 | colou?r 匹配color或colour,但是不能匹配colouur |
+ | 匹配之前的项1次或多次 | Rollno-9+ 匹配Rollno-99、Rollno-9,但是不能匹配Rollno- |
* | 匹配之前的项0次或多次 | co*l 匹配cl、col、coool等 |
() | 创建一个用于匹配的子串 | ma(tri)?x 匹配max或maxtrix |
{n} | 匹配之前的项n次 | 0-9{3} 匹配任意一个三位数,0-9{3} 可以扩展为0-90-9 |
{n,} | 之前的项至少需要匹配n次 | 0-9{2,} 匹配任意一个两位或更多位的数字 |
{n,m} | 指定之前的项所必需匹配的最小次数和最大次数 | 0-9{2,5} 匹配从两位数到五位数之间的任意一个数字 |
| | 交替 : 匹配 | 两边的任意一项 | Oct (1st | 2nd) 匹配Oct 1st 或Oct 2nd |
\ | 转义符可以将上面介绍的特殊字符进行转义 | a.b 匹配a.b,但不能匹配ajb。通过在 . 之间加上前缀 \ ,从而忽略了.的特殊意义 |
POSIX字符类是一个形如[:...:]的特殊元序列(meta sequence),它可以用于匹配特定的字符范围。
正则表达式 | 描 述 | 示 例 |
|---|---|---|
:alnum: | 字母与数字字符 | [:alnum:]+ |
:alpha: | 字母字符(包括大写字母与小写字母) | [:alpha:]{4} |
:blank: | 空格与制表符 | [:blank:]* |
:digit: | 数字字符 | [:digit:]? |
:lower: | 小写字母 | [:lower:]{5,} |
:upper: | 大写字母 | ([:upper:]+)? |
:punct: | 标点符号 | [:punct:] |
:space: | 包括换行符、回车等在内的所有空白字符 | [:space:]+ |
元字符是一种Perl风格的正则表达式,只有一部分文本处理工具支持它,并不是所有的工具都支持下表中所列的字符,但是之前介绍的正则表达式和字符类都是被广泛支持的。
正则表达式 | 描 述 | 示 例 |
|---|---|---|
\b | 单词边界 | \bcool\b 匹配cool,但不匹配coolant |
\B | 非单词边界 | cool\B 匹配coolant,但不匹配cool |
\d | 单个数字字符 | b\db 匹配b2b,但不匹配bcb |
\D | 单个非数字字符 | b\Db 匹配bcb,但不匹配b2b |
\w | 单个单词字符(字母、数字与 _ ) | \w 匹配1或a,但不匹配 & |
\W | 单个非单词字符 | \W匹配&,但不匹配1或a |
\n | 换行符 | \n 匹配一个新行 |
\s | 单个空白字符 | x\sx 匹配x x,但不匹配xx |
\S | 单个非空白字符 | \x\S\x 匹配xkx,但不匹配xx |
\r | 回车 | \r 匹配回车 |
匹配给定文本中的所有单词,可以使用下面的正则表达式:( ?[a-zA-Z]+ ?)“?”用于匹配单词前后可能出现的空格。[a-zA-Z]+ 代表一个或多个字母(a~z和A~Z)。
IP地址,可以使用下面的正则表达式:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
# 或者
[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}我们知道IP地址通常的书写形式是192.168.0.2,它是由点号分割的4个整数(每一个整数的取值范围从0到255)。
[0-9] 或[:digit:] 匹配数字0~9。{1,3} 匹配1到3个数字, \. 匹配 "." 。
正则表达式用$ 、^ 、. 、* 、+ 、{ 以及} 等作为特殊字符。但是如果我们希望将这些字符作为非特殊字符(表示普通字面含义的字符)来使用的话,应该怎么做呢?来看一个例子。
正则表达式:[a-z]*.[0-9]
那么,它是什么意思?
0个或多个 [a-z]([a-z]*) ,接任意单个字符(. ),再接[0-9] 中的任意一个字符,所以它能够匹配 abcdeO9 。[a-z] 中任意一个字符,接单个字符* ,再接单个字符. (点号),最后接一个数字,所以它能够匹配x*.8 。为了避免这种理解上的混乱,我们可以在字符前面放上一个“\ ”(这种做法称为“对字符进行转义”)。对于像 * 这种具有多种含义的字符,可以在前面加上“\ ”,使其具备或丧失某些特殊的含义。至于转义后字符的意义是否具备特殊的含义,则取决于你所使用的工具。
grep 这个命令是一个全局查找正则表达式并且打印结果行的命令。它的输入是一个文件或者是一个标准输入(stdin)。它的输出一般是打印在里屏幕上。 grep 家族里还有 egrep 和 fgrep 这两个命令。
grep 命令在一个或多个文件中查找某个字符模式。如果这个模式中包含空格,就必须用引号把它括起来。 grep命令中,模式可以是一个被引号括括起来的字符串,也可以是单个词,位于模式之后所有的单词都被视为文件名。 grep 将输出发送到屏幕,它不会对输入文件进行任何修改或变化,下面我们以一个命令来说明。
# 命令格式
grep [选项] 模式 [文件....]例子1:
查找文件/etc/passwd中,匹配(含有)root的行。这里面模式就是root,文件为/etc/passwd。
root@vultr:~# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
root@vultr:~# 说明:
指定的文件不是一个合法的文件,屏幕上就会显示报错信息。要查找的模式, grep 就返回退出状态 0,表示成功;要查找的模式,返回的退出状态为 1;指定文件时,退出状态将是 2。grep 的程序输入可以来自标准输入或管道,而不仅仅是文件。
如果忘了指定文件, grep会以为你要它从标准输入(即键盘)获取输入,于是停下来等你健入一些字符。
如果输入来自管道,就会有另一条命令的输出通过管道变成 grep命令的输入,如果匹配到要查找的模式,grep 会把输出打印在屏幕上。
例子2:
ps命令的输出被送到 grep,然后所有包含 /sbin/init 的行都被打印在屏幕上。
root@vultr:~# ps -ef | grep "/sbin/init"
root 1 0 0 Nov22 ? 00:00:16 /sbin/init
root 8272 7862 0 08:21 pts/1 00:00:00 grep --color=auto /sbin/init
root@vultr:~# 元字符也是一种字符,但他表达的含义不同于字符本身的字面含义。例如, ^和$就是元字符。 grep 支持很多正则表达式元字符,以便用户更精确的定义要查找模式。
元字符 | 功 能 | 示 例 | 示例的匹配对象 |
|---|---|---|---|
^ | 行首定位符 | /^love/ | 匹配所有以 love 开头的行 |
$ | 行尾定位符 | /love$/ | 匹配所有以 love 结尾的行 |
. | 匹配除换行外的单个字符 | /l..e/ | 匹配包含字符 l、后跟两个任意字符、再跟字母 e 的行 |
* | 匹配零个或多个前导字符 | /*love/ | 匹配在零个或多个空格紧跟着模式 love 的行 |
[] | 匹配指定字符组内任一字符 | /Llove/ | 匹配包含 love 和 Love 的行 |
^ | 匹配不在指定字符组内任一字符 | /^A-KM-Zove/ | 匹配包含 ove,但 ove 之前的那个字符不在 A至K 或 M至Z 间的行 |
(..) | 保存已匹配的字符 | | |
& | 保存查找串以便在替换串中引用 | s/love/**&**/ | 符号& 代表查找串。字符串 love 将替换前后各加了两个**的引用,即 love 变成**love** |
\< | 词首定位符 | /\<love/ | 匹配包含以 love 开头的单词的行 |
> | 词尾定位符 | /love>/ | 匹配包含以 love 结尾的单词的行 |
x{m} | 连续 m 个 x | /o{5}/ | 出现连续 5个字母o 的行 |
x{m,} | 至少 m 个 x | /o{5,}/ | 至少 5 个连续的 o 的行 |
x{m,n} | 至少m 个 x,但不超过 n个 x | /o{5,10}/ | 5~10 个连续的 o 的行 |
grep 选项用于调整执行查找或显示结果的方式。例如:通过选项来关闭大小写敏感、要求显示行号,或者只显示报错信息等。
选 项 | 功 能 |
|---|---|
-E | 如果加这个选项,那么后面的匹配模式就是扩展的正则表达式,也就是 grep -E = egrep |
-i | 比较字符时忽略大小写区别 |
-w | 把表达式作为词来查找,相当于正则中的"\<...>"(…表示你自定义的规则) |
-x | 被匹配到的内容,正好是整个行,相当于正则"^...$" |
-v | 取反,也就是输出我们定义模式相反的内容 |
-c | count统计,统计匹配结果的行数,主要不是匹配结果的次数,是行数。 |
-m | 只匹配规定的行数,之后的内容就不在匹配了 |
-n | 在输出的结果里显示行号,这里要清楚的是这里所谓的行号是该行内容在原文件中的行号,而不是在输出结果中行号 |
-o | 只显示匹配内容, grep默认是显示满足匹配条件的一行,加上这个参数就只显示匹配结果,比如我们要匹配一个 ip 地址,就只需要结果,而不需要该行的内容。 |
-R | 递归匹配。如果要在一个目录中多个文件或目录匹配内容,则需要这个参数 |
-B | 输出满足条件行的前几行,比如 grep -B 3 "aa" file 表示在 file 中输出有 aa 的行,同时还要输出 aa 的前 3 行 |
-A | 这个与-B 类似,输出满足条件行的后几行 |
-C | 这个相当于同时用-B -A,也就是前后都输出 |
下列所有示例程序都是基于test.txt 的文本数据。
root@vultr:~# cat test.txt
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
root@vultr:~# 打印文件 test.txt 文件包含正则表达式 NW 的行
root@vultr:~# grep NW test.txt
northwest NW Charles Main 3.0 .98 3 34
root@vultr:~# grep ^打印以字母 n 开头的行, (^) 是行首定位符
root@vultr:~# grep ^n test.txt
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
root@vultr:~# 打印所有以数字 4 结尾的行。 ($) 为行尾定位符
root@vultr:~# grep "4$" test.txt
northwest NW Charles Main 3.0 .98 3 34
root@vultr:~# grep '' 或 ""打印所有包含 TB Savage 的行。如果不用引号 (这个例子中,使用单引号或双引号都可以),TB 和 Savage 之间的空格将导致 grep 会在 Savage 和 test.txt 查找 TB。所以,如果字符串之间有空格,必须要用引号引起来。
root@vultr:~# grep 'TB Savage' test.txt
eastern EA TB Savage 4.4 .84 5 20
root@vultr:~# grep .打印所有包含数字 5,后面跟一个.号 再跟一个任意字符的行。 (.)号代表单个字符,被 (\)转义后,只代表本身一个.号。
root@vultr:~# grep '5\..' test.txt
western WE Sharon Gray 5.3 .97 5 23
southern SO Suan Chin 5.1 .95 4 15
northeast NE AM Main Jr. 5.1 .94 3 13
central CT Ann Stephens 5.7 .94 5 13
root@vultr:~# grep []打印所有字母 w 和 e 开头的行。 []表示任意一个字符都可以匹配。
root@vultr:~# grep '^[we]' test.txt
western WE Sharon Gray 5.3 .97 5 23
eastern EA TB Savage 4.4 .84 5 20
root@vultr:~# grep [^]打印包含非数字字符的行。由于至少每一行有一个非数字字符,因此所有行都被打印。
root@vultr:~# grep '[^0-9]' test.txt
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
root@vultr:~# grep '[]'打印了包含两个大写字符、后跟一个空格和一个大写字符的行,例如 TB Savage 和 AM Main。
root@vultr:~# grep '[A-Z][A-Z] [A-Z]' test.txt
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
root@vultr:~# grep *打印包含一个s、后跟 0 个或多个连着的s 和一个空格的文本行。
root@vultr:~# grep 'ss* ' test.txt
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
central CT Ann Stephens 5.7 .94 5 13
root@vultr:~# grep {}打印所有出现至少 9 个小写字母连在一起的行,例如, northwest, southwest, southeast,northeast。
root@vultr:~# grep '[a-z]\{9\}' test.txt
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
southeast SE Patricia Hemenway 4.0 .7 4 17
northeast NE AM Main Jr. 5.1 .94 3 13
root@vultr:~# grep \(\)如果某一行包含一个 3后面跟一个句点和一个数字,再任意多个字符(.*),然后跟一个或任意多个空格,再接一个3,则打印该行。
其中 \(3\) 将字符3保存下来,后面用\1 进行代表字符 3。
root@vultr:~# grep '\(3\)\.[0-9].*\1 *\1' test.txt
northwest NW Charles Main 3.0 .98 3 34
root@vultr:~# grep \<Word\>打印所有包含单词 north 的行。“ \<”是词首定位符,“ \>”是词尾定位符。
root@vultr:~# grep '\<north\>' test.txt
north NO Margot Weber 4.5 .89 5 9
root@vultr:~# grep \<Word2>\打印所有包含以小写字母开头,以 n 结尾,中间由任意多个字符组成的单词的行。注意 符号.*,他代表任意字符,包括空格。
root@vultr:~# grep '\<[a-z].*n\>' test.txt
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southern SO Suan Chin 5.1 .95 4 15
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
central CT Ann Stephens 5.7 .94 5 13
root@vultr:~# 选项-n 在找到指定模式的行前面加上其行号再一并输出(显示的行号是文本中的行号)。
root@vultr:~# grep -n 'north' test.txt
1:northwest NW Charles Main 3.0 .98 3 34
7:northeast NE AM Main Jr. 5.1 .94 3 13
8:north NO Margot Weber 4.5 .89 5 9
root@vultr:~# 选项-i 关闭大小写敏感性。表达式 pat 包含任意大小写的组合都符合。
root@vultr:~# grep -i 'pat' test.txt
southeast SE Patricia Hemenway 4.0 .7 4 17
root@vultr:~# 这个实例中,选项-v 打印所有不含模式 2或3或5 的行。
选项-v 可用来删除输入文件汇中特定的条目。如果真要删除这些条目,就要把 grep 的输出重定向到一个临时文件中,然后把临时文件的名字改成原文件的名字。
注意不能从原文件重定向到原文件,这样会破坏原文件的。
root@vultr:~# grep -v '[235]' test.txt
southeast SE Patricia Hemenway 4.0 .7 4 17
root@vultr:~# 选项-l 使 grep 只输出包含模式的文件名,而不输出文本行。
root@vultr:~# grep -l 'north' test.txt t2.sh
test.txt
root@vultr:~# 选项-c 让 grep 打印出含有模式的行的数目。这个数字并不代表模式的出现次数。例如,即使 west 在某行中出现 2 次,这行也只计一次。
root@vultr:~# grep -c 'north' test.txt
3
root@vultr:~# 选项-w只查找作为一个词,而不是词的一部分出现的模式。这条命令只打印包含词 north 的行,而不打印那些northwest、 northwest 等中出现的行。
root@vultr:~# grep 'north' test.txt
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
root@vultr:~# grep -w 'north' test.txt
north NO Margot Weber 4.5 .89 5 9
root@vultr:~# grep 的输入不一定都是文件,它也常常从管道读取输入。
root@vultr:~# ls
code control_vpn restart_ss.sh showUsed_ss.sh t2.sh test.txt
root@vultr:~# ls | grep "^s"
showUsed_ss.sh
root@vultr:~# ls | grep "s"
restart_ss.sh
showUsed_ss.sh
t2.sh
test.txt
root@vultr:~# egrep 在 grep 的基础上增加了更多的元字符。但是 egrep 不允许使用\(\), \{\}
元字符 | 功 能 | 示 例 | 示例的匹配对象 |
|---|---|---|---|
^ | 行首定位符 | /^love/ | 匹配所有以 love 开头的行 |
$ | 行尾定位符 | /love$/ | 匹配所有以 love 结尾的行 |
. | 匹配除换行外的单个字符 | /l..e/ | 匹配包含字符 l、后跟两个任意字符、再跟字母 e 的行 |
* | 匹配零个或多个前导字符 | /*love/ | 匹配在零个或多个空格紧跟着模式 love 的行 |
[] | 匹配指定字符组内任一字符 | /Llove/ | 匹配包含 love 和 Love 的行 |
^ | 匹配不在指定字符组内任一字符 | /^A-KM-Zove/ | 匹配包含 ove,但 ove 之前的那个字符不在 A至K 或 M至Z 间的行 |
egrep | 新增的元字符: | | |
+ | 匹配一个或多个加号前面的字符 | 'a-z+ove' | 匹配一个或多个小写字母后跟 ove 的字符串。 move love approve |
? | 匹配 0 个或一个前导字符 | 'lo?ve' | 匹配 l 后跟一个或 0 个字母 o 以及 ve 的字符串。 love或者lve |
a|b | 匹配 a 或 b | 'love|hate' | 匹配 love 和 hate 这两个表达式之一 |
() | 字符组 | 'love(able|ly)(ov+)' | 匹配 loveable 或 lovely, 匹配 ov的一次或多次出现 |
grep 不支持“|”这个, egrep 支持“|”, egrep 查到了包含 west 或者 north 的行。
root@vultr:~# grep "west|north" test.txt
root@vultr:~# egrep "west|north" test.txt
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
root@vultr:~# OK!
以上,Enjoy~