Linux Shell编程(5) - 正则表达式
一、正则表达式简介
1. 正则表达式是什么
正则表达式用于描述字符排列和匹配模式的一种语法规则。 它主要用于字符串的模式分割、匹配、查找及替换操作。
2. 正则表达式与通配符
/ | 正则表达式 | 通配符 |
---|---|---|
匹配主体 | 文件中的内容 | 文件名 |
匹配规则 | 包含匹配 | 完全匹配 |
常用命令 | grep ,awk ,sed | ls ,find ,cp |
3. 通配符
*
:匹配任意0到多个字符?
:匹配任意一个字符[]
:匹配括号中的一个字符*
匹配任意0到多个字符
- 目录下有5个文件,1个子目录
[root/tmp/tmp]# ll 总用量 0 -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 a.conf -rw-r--r-- 1 root root 0 5月 31 03:37 a.md -rw-r--r-- 1 root root 0 5月 31 03:37 bbb.md -rw-r--r-- 1 root root 0 5月 31 03:37 bc.ini drwxr-xr-x 2 root root 58 5月 31 03:39 sh/
- 列出目录下所有文件,包含子目录中的文件
[root/tmp/tmp]# ll * -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 a.conf -rw-r--r-- 1 root root 0 5月 31 03:37 a.md -rw-r--r-- 1 root root 0 5月 31 03:37 bbb.md -rw-r--r-- 1 root root 0 5月 31 03:37 bc.ini sh: 总用量 0 -rw-r--r-- 1 root root 0 5月 31 03:39 asd.sh -rw-r--r-- 1 root root 0 5月 31 03:38 qwe.sh -rw-r--r-- 1 root root 0 5月 31 03:39 rty.sh -rw-r--r-- 1 root root 0 5月 31 03:39 zxc.sh
- 列出以
a
开头和以sh
开头的文件
[root/tmp/tmp]# ll a* -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 a.conf -rw-r--r-- 1 root root 0 5月 31 03:37 a.md [root/tmp/tmp]# ll sh* 总用量 0 -rw-r--r-- 1 root root 0 5月 31 03:39 asd.sh -rw-r--r-- 1 root root 0 5月 31 03:38 qwe.sh -rw-r--r-- 1 root root 0 5月 31 03:39 rty.sh -rw-r--r-- 1 root root 0 5月 31 03:39 zxc.sh
- 因为通配符是完全匹配,所以
a*c
匹配不到文件,必须用a*c*
[root/tmp/tmp]# ll a*c ls: 无法访问a*b: 没有那个文件或目录 [root/tmp/tmp]# ll a*c* -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 a.conf
- 匹配字目录中的文件
[root/tmp/tmp]# ll s*a* ls: 无法访问s*a*: 没有那个文件或目录 [root/tmp/tmp]# ll s*/a* -rw-r--r-- 1 root root 0 5月 31 03:39 sh/asd.sh
?
匹配任意一个字符
[root/tmp/tmp]# ll 总用量 0 -rw-r--r-- 1 root root 0 5月 31 03:59 aaa.ini -rw-r--r-- 1 root root 0 5月 31 03:37 aaa.md -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 bbb.md -rw-r--r-- 1 root root 0 5月 31 03:37 cbc.ini drwxr-xr-x 2 root root 58 5月 31 03:39 sh/ [root/tmp/tmp]# find . -name '?bc.ini' ./abc.ini ./cbc.ini [root/tmp/tmp]# find . -name '???.md' ./bbb.md ./aaa.md [root/tmp/tmp]# find . -name 'a??.ini' ./abc.ini ./aaa.ini [root/tmp/tmp]# find . -name 's?' ./sh
[]
匹配括号中的一个字符
[root/tmp/tmp]# ll 总用量 0 -rw-r--r-- 1 root root 0 5月 31 03:59 aaa.ini -rw-r--r-- 1 root root 0 5月 31 03:37 aaa.md -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 bbb.md -rw-r--r-- 1 root root 0 5月 31 03:37 cbc.ini drwxr-xr-x 2 root root 58 5月 31 03:39 sh/ [root/tmp/tmp]# ll [a-z]bc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 cbc.ini [root/tmp/tmp]# ll [ab]bc.ini -rw-r--r-- 1 root root 0 5月 31 03:37 abc.ini
二、基础正则表达式
元字符 | 作用 |
---|---|
* | 前一个字符匹配0次或任意多次 |
. | 匹配除了换行符以外的任意一个字符 |
^ | 匹配行首。例如:^hello 会匹配以 hello 开头的行 |
$ | 匹配行尾。例如:hello$ 会匹配以 hello 结尾的行 |
[] | 匹配括号中任意一个字符,只匹配一个字符。例如:[aeiou] 匹配任意一个元音字符[0-9] 匹配任意一个数字[a-z] 匹配任意一个小写字母 |
[^] | 取反,匹配括号中字符以外的任意一个字符。例如:[^0-9] 匹配任意一个非数字字符[^a-z] 匹配任意一个非小写字母字符 |
\ | 转义符,用于取消特殊符号的含义。例如:\. 匹配符号 '.' |
\{n\} | 表示其前面的字符恰好出现n次。 |
\{n,\} | 表示其前面的字符至少出现n次。 |
\{n,m\} | 表示其前面的字符至少出现n次,最多出现m次。 |
0. 测试用文档
使用grep -n '[正则表达式]' [文件]
命令来输出匹配的行,并显示行号。- test.md
1 a 2 aa 3 aaa 4 aaaa 5 aaaaa 6 7 b 8 bb 9 bbb 10 bbbb 11 bbbbb 12 13 ab 14 aab 15 abcb 16 abcde 17 18 said 19 soid 20 suud 21 sooooood 22 23 023456 24 1223456 25 123 26 3445 27 425asdf 28 dasd1234ff 29 30 3.1415926 31 hello world. 32 33 2018-05-31 34 2017-02-22 35 36 192.168.33.10 37 255.255.255.255 38 0.0.0.0
1. *
前一个字符匹配0次或任意多次
2. .
匹配除了换行符以外的任意一个字符
.*
匹配所有内容,包括空白行s..d
匹配在 s 和 d 之间有两个字符的行
[root/tmp]# grep -n 's..d' test.md 18:said 19:soid 20:suud
a.c
匹配在 a 和 c 之间有一个字符的行
[root/tmp]# grep -n 'a.c' test.md 15:abcb 16:abcde
a.*d
匹配在 a 和 d 之间有任意0到多个字符的行
[root/tmp]# grep -n 'a.*d' test.md 16:abcde 18:said 27:425asdf 28:dasd1234ff
3. ^
匹配行首,$
匹配行尾
^s
匹配以 s 开头的行
[root/tmp]# grep -n '^s' test.md 18:said 19:soid 20:suud 21:sooooood
d$
匹配以 d 结尾的行
[root/tmp]# grep -n 'd$' test.md 18:said 19:soid 20:suud 21:sooooood
^$
匹配所有空行
[root/tmp]# grep -n '^$' test.md 6: 12: 17: 22: 29: 32: 35:
4. []
|匹配括号中任意一个字符,只匹配一个字符。
s[aeiou]id
匹配 s 和 id 之间只有一个元音字母的行
[root/tmp]# grep -n 's[aeiou]id' test.md 18:said 19:soid
s[aeiou]*d
匹配 s 和 d 之间只有任意0个或多个元音字母的行
[root/tmp]# grep -n 's[aeiou]*d' test.md 18:said 19:soid 20:suud 21:sooooood 27:425asdf 28:dasd1234ff
[4-6]
匹配包含 4-6 之间的任意一个数字的行
[root/tmp]# grep -n '[4-6]' test.md 23:023456 24:1223456 26:3445 27:425asdf 28:dasd1234ff 30:3.1415926 33:2018-05-31 36:192.168.33.10 37:255.255.255.255
^[c-z]
匹配以 c-z 之间的任意一个小写字母开头的行
[root/tmp]# grep -n '^[c-z]' test.md 18:said 19:soid 20:suud 21:sooooood 28:dasd1234ff 31:hello world.
5. [^]
取反,匹配括号中字符以外的任意一个字符
^[^a-z]
匹配不以小写字母开头的行
[root/tmp]# grep -n '^[^a-z]' test.md 23:023456 24:1223456 25:123 26:3445 27:425asdf 30:3.1415926 33:2018-05-31 34:2017-02-22 36:192.168.33.10 37:255.255.255.255 38:0.0.0.0
[^a-z0-9]
匹配包含非数字和小写字母的行
[root/tmp]# grep -n '[^a-z0-9]' test.md 30:3.1415926 31:hello world. 33:2018-05-31 34:2017-02-22 36:192.168.33.10 37:255.255.255.255 38:0.0.0.0
6. \
|转义符,用于取消特殊符号的含义
\.
匹配包含 '.' 的行
[root/tmp]# grep -n '\.' test.md 30:3.1415926 31:hello world. 36:192.168.33.10 37:255.255.255.255 38:0.0.0.0
\.$
匹配以 '.' 结尾的行
[root/tmp]# grep -n '\.$' test.md 31:hello world.
7. \{n\}
表示其前面的字符恰好出现n次
a\{3\}
匹配 a 连续出现 3 次的行
[root/tmp]# grep -n 'a\{3\}' test.md 3:aaa 4:aaaa 5:aaaaa
[0-9]\{5\}
匹配包含连续5个数字的行
[root/tmp]# grep -n '[0-9]\{5\}' test.md 23:023456 24:1223456 30:3.1415926
8. \{n,\}
表示其前面的字符至少出现n次
a\{3,\}
匹配 a 至少连续出现 3 次的行
[root/tmp]# grep -n 'a\{3,\}' test.md 3:aaa 4:aaaa 5:aaaaa
[0-9]\{5,\}
匹配包含至少连续5个数字的行
[root/tmp]# grep -n '[0-9]\{5,\}' test.md 23:023456 24:1223456 30:3.1415926
9. \{n,m\}
表示其前面的字符至少出现n次,最多出现m次。
s[a-z]\{2,5\}d
匹配 s 和 d 之间至少有2个字母,最多有5个字母的行
[root/tmp]# grep -n 's[a-z]\{2,5\}d' test.md 18:said 19:soid 20:suud
三、几个实例
1. 匹配日期格式 'YYYY-MM-DD'
并非严格匹配日期格式,实际上是匹配 '9999-99-99'[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}
[root/tmp]# grep -n '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}' test.md 33:2018-05-31 34:2017-02-22
[0-9]\{4\}\(-[0-9]\{2\}\)\{2\}
[root/tmp]# grep -n '[0-9]\{4\}\(-[0-9]\{2\}\)\{2\}' test.md 33:2018-05-31 34:2017-02-22
2. 匹配IP地址
并非严格匹配IP地址,实际上是匹配 0.0.0.0 - 999.999.999.999,而实际IP地址只到 255.255.255.255[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}
[root/tmp]# grep -n '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' test.md 36:192.168.33.10 37:255.255.255.255 38:0.0.0.0
[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}
[root/tmp]# grep -n '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' test.md 36:192.168.33.10 37:255.255.255.255 38:0.0.0.0
相关推荐
wangzhaotongalex 2020-10-20
rechanel 2020-11-16
wyq 2020-11-11
TLROJE 2020-10-26
风雨断肠人 2020-10-13
duanqingfeng 2020-09-29
cshanzhizi 2020-10-16
luofuIT成长记录 2020-09-22
phphub 2020-09-10
taomengxing 2020-09-07
MaggieRose 2020-08-19
flyingssky 2020-08-18
山水沐光 2020-08-18
jyj00 2020-08-15
AHuqihua 2020-08-09
山水沐光 2020-08-03