REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符
正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等
正则表达式分两类:
正则表达式引擎:
采用不同算法,检查处理正则表达式的软件模块,如:PCRE(Perl Compatible Regular Expressions)
正则表达式的元字符分类:字符匹配、匹配次数、位置锚定、分组
帮助:man 7 regex
. 匹配任意单个字符,可以是一个汉字
[] 匹配指定范围内的任意单个字符,示例:[wang] [0-9] [a-z] [a-zA-Z]
[^] 匹配指定范围外的任意单个字符,示例:[^wang]
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
\w #匹配单词构成部分,等价于[_[:alnum:]]
\W #匹配非单词构成部分,等价于[^_[:alnum:]]
\S #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\s #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意
Unicode 正则表达式会匹配全角空格符
范例:
[root@centos8 ~]#ls /etc/ | grep 'rc[.0-6]'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[root@centos8 ~]#ls /etc/ | grep 'rc[.0-6].'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[root@centos8 ~]#ls /etc/ | grep 'rc[.0-6]\.'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
用在要指定次数的字符后面,用于指定前面的字符要出现的次数
* 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* 任意长度的任意字符
\? 匹配其前面的字符0或1次,即:可有可无
\+ 匹配其前面的字符至少1次,即:肯定有,>=1
\{n\} 匹配前面的字符n次
\{m,n\} 匹配前面的字符至少m次,至多n次
\{,n\} 匹配前面的字符至多n次,<=n
\{n,\} 匹配前面的字符至少n次
范例:
[root@centos8 ~]#echo /etc/ |grep "/etc/\?"
/etc/
[root@centos8 ~]#echo /etc |grep "/etc/\?"
/etc
范例:
[root@centos8 ~]#cat test.txt
google
goooooooooooooooooogle
ggle
gogle
gooooOOOOO00000gle
gooogle
[root@centos8 ~]#grep 'go\{2,\}gle' test.txt
google
goooooooooooooooooogle
gooogle
[root@centos8 ~]#grep 'goo\+gle' test.txt
google
goooooooooooooooooogle
gooogle
[root@centos8 ~]#grep 'goo*gle' test.txt
google
goooooooooooooooooogle
gogle
gooogle
[root@centos8 ~]#grep 'gooo*gle' test.txt
google
goooooooooooooooooogle
gooogle
范例:匹配正负数
[root@centos8 ~]#echo -1 -2 123 -123 234 |grep '-\?[0-9]\+'
grep: invalid option -- '\'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
[root@centos8 ~]#echo -1 -2 123 -123 234 |grep '\-\?[0-9]\+'
-1 -2 123 -123 234
[root@centos8 ~]#echo -1 -2 123 -123 234 |grep -E '-?[0-9]+'
grep: invalid option -- '?'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
[root@centos8 ~]#echo -1 -2 123 -123 234 |grep -E '\-?[0-9]+'
-1 -2 123 -123 234
[root@centos8 ~]#echo -1 -2 123 -123 234 |grep -E -- '-?[0-9]+'
-1 -2 123 -123 234
[root@centos8 ~]#echo -1 -2 123 -123 234 |grep -E '(-)?[0-9]+'
-1 -2 123 -123 234
[root@CentOS-8 ~]#ifconfig ens160
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.100 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::e765:5eea:380f:1b65 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:97:15:e6 txqueuelen 1000 (Ethernet)
RX packets 21674 bytes 31492240 (30.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6492 bytes 391869 (382.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@CentOS-8 ~]#ifconfig ens160|grep netmask |grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'|head -n1
10.0.0.100
[root@CentOS-8 ~]#ifconfig ens160|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'|head -n1
10.0.0.100
位置锚定可以用于定位出现的位置
^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
\< 或 \b 词首锚定,用于单词模式的左侧
\> 或 \b 词尾锚定,用于单词模式的右侧
\<PATTERN\> 匹配整个单词
#注意: 单词是由字母,数字,下划线组成
范例:
[root@CentOS-8 ~]#grep '^#' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Wed Apr 21 02:44:34 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
[root@CentOS-8 ~]#grep '^[^#]' /etc/fstab
UUID=cf2b160d-f6f8-4334-a54f-d380d3bd71fe / xfs defaults 0 0
UUID=394e8449-008a-4b68-8402-37429a5d9486 /boot xfs defaults 0 0
UUID=83325e3f-18bf-4e14-a6a8-6e53a761629d /home xfs defaults 0 0
UUID=faa14c8d-3932-41c2-a9c6-d80c41c54d4e none swap defaults 0 0
范例:排除掉空行和#开头的行
[root@centos8 ~]#grep -v '^$' /etc/profile|grep -v '^#'
[11:19:27 root@CentOS-8 ~]#vim test.txt
[11:19:42 root@CentOS-8 ~]#cat -A test.txt
google$
abc google xyz $
gooogle $
$
$
[root@CentOS-8 ~]#grep '^[[:space:]]*$' test.txt
[root@CentOS-8 ~]#grep '^[[:space:]]*$' test.txt -n
4:
5:
[root@CentOS-8 ~]#cat -A test.txt -n
1 google$
2 abc google xyz $
3 gooogle $
4 $
5 $
[root@CentOS-8 ~]#echo hello_123|grep '\<123'
[root@CentOS-8 ~]#echo hello-123|grep '\<123'
hello-123
[root@CentOS-8 ~]#echo helloA123|grep '\<123'
[root@CentOS-8 ~]#echo hello:123|grep '\<123'
hello:123
[root@CentOS-8 ~]#echo hello 123|grep '\<123'
hello 123
[root@CentOS-8 ~]#echo hello 123|grep '123\>'
hello 123
[root@CentOS-8 ~]#echo hello 123|grep 'hello\>'
hello 123
[root@CentOS-8 ~]#echo hello 123|grep 'hello\>'
hello 123
[root@CentOS-8 ~]#echo hello 123|grep '\'
hello 123
[root@CentOS-8 ~]#echo hello_123|grep '\'
[root@CentOS-8 ~]#echo hello:123|grep '\'
hello:123
[root@CentOS-8 ~]#ifconfig eth0
eth0: error fetching interface information: Device not found
[root@CentOS-8 ~]#ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.100 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::e765:5eea:380f:1b65 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:97:15:e6 txqueuelen 1000 (Ethernet)
RX packets 28183 bytes 38688075 (36.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8765 bytes 571527 (558.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:af:fa:3e txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@CentOS-8 ~]#ifconfig ens160
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.100 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::e765:5eea:380f:1b65 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:97:15:e6 txqueuelen 1000 (Ethernet)
RX packets 28201 bytes 38689819 (36.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8782 bytes 574853 (561.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@CentOS-8 ~]#ifconfig ens160|grep netmask
inet 10.0.0.100 netmask 255.255.255.0 broadcast 10.0.0.255
[root@CentOS-8 ~]#ifconfig ens160|grep netmask|tr -s ' '
inet 10.0.0.100 netmask 255.255.255.0 broadcast 10.0.0.255
[root@CentOS-8 ~]#ifconfig ens160|grep netmask|tr -s ' '|cut -d " " -f3
10.0.0.100
[root@CentOS-8 ~]#ifconfig ens160|grep netmask|grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.'
[root@CentOS-8 ~]#ifconfig ens160|grep netmask|grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
inet 10.0.0.100 netmask 255.255.255.0 broadcast 10.0.0.255
[root@CentOS-8 ~]#ifconfig ens160|grep netmask|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
10.0.0.100
255.255.255.0
10.0.0.255
[root@CentOS-8 ~]#ifconfig ens160|grep netmask|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' |head -1
10.0.0.100
[root@CentOS-8 ~]#ifconfig ens160|grep -i mask|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' |head -1
10.0.0.100
[root@CentOS-8 ~]#hostname -I
10.0.0.100 192.168.122.1
分组:() 将多个字符捆绑在一起,当作一个整体处理,如:(root)+
后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, …
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
示例:
\(string1\(string2\)\)
\1 :string1\(string2\)
\2 :string2
[root@CentOS-8 ~]#echo abcabcabc|grep "abc\{3\}"
[root@CentOS-8 ~]#echo abcabcabccc|grep "abc\{3\}"
abcabcabccc
[root@CentOS-8 ~]#echo abcabcabccc|grep "\(abc\)\{3\}"
abcabcabccc
[root@CentOS-8 ~]#echo abcabcabc|grep "\(abc\)\{3\}"
abcabcabc
注意: 后向引用
引用前面的分组括号中的模式所匹配字符,而非模式本身
或者:\|
示例:
a\|b #a或b
C\|cat #C或cat
\(C\|c\)at #Cat或cat
[root@CentOS-8 ~]#echo 1|grep "1\|2"
1
[root@CentOS-8 ~]#echo 2|grep "1\|2"
2
[root@CentOS-8 ~]#echo 3|grep "1\|2"
[root@CentOS-8 ~]#echo 1abc|grep "1\|2abc"
1abc
[root@CentOS-8 ~]#echo 1abc|grep "1abc\|2abc"
1abc
[root@CentOS-8 ~]#echo 1abc|grep "\(1\|2\)abc"
1abc
[root@CentOS-8 ~]#ifconfig ens160|grep -i mask|grep -o '\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}' |head -1
10.0.0.100
范例:排除空行和#开头的行
[root@centos6 ~]#grep -v '^#' /etc/httpd/conf/httpd.conf |grep -v ^$
[root@centos6 ~]#grep -v '^#\|^$' /etc/httpd/conf/httpd.conf
[root@centos6 ~]#grep -v '^\(#\|$\)' /etc/httpd/conf/httpd.conf
[root@centos6 ~]#grep "^[^#]" /etc/httpd/conf/httpd.conf
正则表达式练习
1、显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法)
2、显示/etc/passwd文件中不以/bin/bash结尾的行
3、显示用户rpc默认的shell程序
4、找出/etc/passwd中的两位或三位数
5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空白字符的行
6、找出“netstat -tan”命令结果中以LISTEN后跟任意多个空白字符结尾的行
7、显示CentOS7上所有UID小于1000以内的用户名和UID
8、添加用户bash、testbash、basher、sh、nologin(其shell为/sbin/nologin),找出/etc/passwd用户名和shell同名的行
9、利用df和grep,取出磁盘各分区利用率,并从大到小排序
. 任意单个字符
[wang] 指定范围的字符
[^wang] 不在指定范围的字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
* 匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
^ 行首
$ 行尾
\<, \b 语首
\>, \b 语尾
[root@CentOS-8 ~]#ifconfig ens160|grep -i mask|grep -o '\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}' |head -1
10.0.0.100
[root@CentOS-8 ~]#ifconfig ens160|grep -i mask|grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' |head -1
10.0.0.100
() 分组
后向引用:\1, \2, ...
| 或者
a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat
扩展正则表达式练习
1、显示三个用户root、mage、wang的UID和默认shell
2、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
3、使用egrep取出/etc/rc.d/init.d/functions中其基名
4、使用egrep取出上面路径的目录名
5、统计last命令中以root登录的每个主机IP地址登录次数
6、利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255
7、显示ifconfig命令结果中所有IPv4地址
8、将此字符串:welcome to magedu linux 中的每个字符去重并排序,重复次数多的排到前面