SRE运维工程师笔记-正则表达式

内容概述

  • 基本正则表达式和扩展正则表达式

1. 正则表达式

REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符

正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等

正则表达式分两类:

  • 基本正则表达式:BRE Basic Regular Expressions
  • 扩展正则表达式:ERE Extended Regular Expressions

正则表达式引擎:

采用不同算法,检查处理正则表达式的软件模块,如:PCRE(Perl Compatible Regular Expressions)

正则表达式的元字符分类:字符匹配、匹配次数、位置锚定、分组

帮助:man 7 regex

1.1 基本正则表达式元字符

1.1.1 字符匹配

. 匹配任意单个字符,可以是一个汉字
[] 匹配指定范围内的任意单个字符,示例:[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

1.1.2 匹配次数

用在要指定次数的字符后面,用于指定前面的字符要出现的次数

* 匹配前面的字符任意次,包括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

在这里插入图片描述
范例:取IP地址

[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

1.1.3 位置锚定

位置锚定可以用于定位出现的位置

^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^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\>'
hello 123
[root@CentOS-8 ~]#echo hello_123|grep '\<hello\>'
[root@CentOS-8 ~]#echo hello:123|grep '\<hello\>'
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 

1.1.4 分组其它

1.1.4.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

注意: 后向引用 引用前面的分组括号中的模式所匹配字符,而非模式本身

1.1.4.2 或者

或者:\|
示例:

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,取出磁盘各分区利用率,并从大到小排序

1.2 扩展正则表达式

1.2.1 字符匹配元字符

. 任意单个字符
[wang] 指定范围的字符
[^wang] 不在指定范围的字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号

1.2.2 次数匹配

*       匹配前面字符任意次
?      0或1次
+      1次或多次
{n}    匹配n次
{m,n}  至少m,至多n次

1.2.3 位置锚定

^ 行首
$ 行尾
\<, \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.4 分组其它

() 分组
后向引用:\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 中的每个字符去重并排序,重复次数多的排到前面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值