正则表达式
1.1 注意事项
- 正则符号都是英文符号,避免使用中文符号。
- 推荐使用 grep/egrep 命令,默认设置了别名,自动加上颜色。
- 分析正则与正则匹配到的内容。
- 其他坑。
#'' "" .
#'' "" 。
alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
1.2 符号概述
正则:regular expression RE
正则表达式 regular expression regexp | 符号 |
---|---|
基础正则 BRE(Basic RE) | ^ $ . * .* [] [^] |
扩展正则 ERE(Extended RE) 121 | | + () {} ? |
Perl 语言正则 (其他) |
1.3 基础正则
- 三剑客命令默认支持的正则。
1)^ 以…… 开头的行
英文的符号,如果是中文的 ^ 是省略号。
- 以 I 开头的行
[root@oldboy-85-vip-king-v2 oldboy]# grep '^m' re.txt
my blog is http://oldboy.blog.51cto.com
my qq is 49000448
my god ,i am not oldbey,but OLDBOY!
[root@oldboy-85-vip-king-v2 oldboy]# grep '^my' re.txt
my blog is http://oldboy.blog.51cto.com
my qq is 49000448
my god ,i am not oldbey,but OLDBOY!
2)$ 以…… 结尾的行
- 以数字 8 结尾的行
[root@oldboy-85-vip-king-v2 oldboy]# grep '8$' re.txt
my qq is 49000448
cat -A 显示出文件中的特殊隐藏符号.
^m$ 匹配了什么?
匹配:m
3)^$ 空行,这行中没有任何字符
- 过滤出文件中的空行并显示行号
[root@oldboy-85-vip-king-v2 oldboy]# grep -n '^$' re.txt
3:
7:
10:
- 排除空行
[root@oldboy-85-vip-king-v2 oldboy]# grep -nv '^$' re.txt
1:I am oldboy teacher!
2:I teach linux.
4:I like badminton ball ,billiard ball and chinese chess!
5:my blog is http://oldboy.blog.51cto.com
6:our size is http://blog.oldboyedu.com
8:my qq is 49000448
9:not 4900000448.
11:my god ,i am not oldbey,but OLDBOY!
- 正则案例:排除
/etc/ssh/sshd_config
文件中的空行,然后排除以 #号开头的行(可以使用管道)
grep -v '^$' /etc/ssh/sshd_config |grep -v '^#'
应用建议:用于排除文件中的空行使用,排除空行和带井号的行。
4). 任意一个字符,不匹配空行
- oldb 任意一个字符 y
[root@oldboy83-prod oldboy]# grep 'oldb.y' re.txt
I am oldboy teacher!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my god ,i am not oldbey,but OLDBOY!
[root@oldboy83-prod oldboy]#
. 不会匹配空行。
- grep -o 选项,显示正则匹配到了什么?显示执行过程。
[root@oldboy-85-vip-king-v2 oldboy]# grep '.' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY![root@oldboy-85-vip-king-v2 oldboy]# grep -o '.' re.txt
I
a
m
o
l
d
b
o
5)\ 转义字符 去掉特殊符号的含义。
- 找出文件中以.(点)结尾的行
[root@oldboy-85-vip-king-v2 oldboy]# cat re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY![root@oldboy-85-vip-king-v2 oldboy]# grep '.$' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY![root@oldboy-85-vip-king-v2 oldboy]# grep '\.$' re.txt
I teach linux.
not 4900000448.
6)* 前一个字符连续出现 0 次或 0 次以上。
-
什么是连续出现 / 重复。111,数字1连续出现3次
-
出现 0 次:这个符号没有的意思。
-
0次或以上(匹配全部)
[root@oldboy83-prod oldboy]# grep '0*' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY![root@oldboy83-prod oldboy]# grep '' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY!
7).* 所有,任何字符
使用频率非常高的符号。
- . 任意一个字符
- *前一个字符连续出现 0 次或 0 次以上
- .* 表示所有。
- 以任意内容开头直到匹配到 am 字符的行:
[root@oldboy83-prod oldboy]# cat re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY!#以任意内容开头直到匹配到am字符的行
[root@oldboy83-prod oldboy]# grep '^.*am' re.txt
I am oldboy teacher!
my god ,i am not oldbey,but OLDBOY!
8)[] [abc] 表示匹配任意 1 个字符,a 或 b 或 c,中括号相当于一个字符
使用频率较高的正则。
()小括号
[] 中括号
{} 大括号 花括号
- [abc]
[root@oldboy83-prod oldboy]# grep '[abc]' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my god ,i am not oldbey,but OLDBOY!
[root@oldboy83-prod oldboy]# grep '[abc][abc]' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
[root@oldboy83-prod oldboy]# grep -o '[abc][abc]' re.txt
ac
ac
ba
ba
ba
- 匹配数字
grep '[0-9]' re.txt
- 匹配小写字母
[a-z]
- 匹配大写字母
[A-Z]
- 匹配大小写字母
[a-zA-Z]
[a-Z] #如果这个用不了使用上面完成形式
- 匹配大小写字母 + 数字
grep '[a-zA-Z0-9]' re.txt
grep '[a-z0-9]' re.txt
grep '[0-Z]' re.txt
- 匹配出以字母 m 或 n 开头的行
[root@oldboy83-prod oldboy]# grep '^[mn]' re.txt
my blog is http://oldboy.blog.51cto.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY!
[root@oldboy83-prod oldboy]#
- 匹配出以. 或空格或!结尾的行
[root@oldboy83-prod oldboy]# grep '[.! ]$' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
not 4900000448.
my god ,i am not oldbey,but OLDBOY!
提示:[] 中会自动去掉符号的特殊含义
- 小结:
- [a-z] [A-Z] [0-9] [a-z] [0-Z]
- 自动去掉特殊含义,不需要再次进行转义。
- [] 未来与扩展正则 + 一起使用较多。
9)[ ^abc] 表示匹配除了 a、b、c 之外的任意一个字符
[root@oldboy83-prod oldboy]# grep '[^abc]' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY!
10)小结基础正则
基础正则 | 含义 |
---|---|
^ | 以 xxx 开头的行 |
$ | 以… 结尾的行 |
^$ | 空行 |
. | 任意一个字符 |
\ | 转义字符,撬棍 |
* | 前一个字符出现 0 次或 0 次以上 |
.* | 所有 |
[] | [abc] a 或 b 或 c,[] 相当于是 1 个字符 |
[^] | [^abc] 匹配除了 abc 之外的内容,[] 相当于是 1 个字符 |
1.4 扩展正则
- grep≡egrep 或 grep -E
- sed 使用 sed -r 支持扩展正则
- awk 默认支持扩展正则。
#Linux三剑客如何支持扩展正则
##grep命令,推荐使用前2个.
egrep '0+' re.txt
grep -E '0+' re.txt
grep '0\+' re.txt
##sed 需要使用-r选项
##awk 直接支持扩展正则.
1)+ 前一个字符连续出现 1 次或 1 次以上
- + 大部分配合着 [] 一起使用。
- 取出连续出现的 0
[root@oldboy83-prod oldboy]# egrep '0+' re.txt
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]# grep -E '0+' re.txt (表示启用扩展正则表达式模式(等同于 egrep))
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]# grep '0\+' re.txt
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]#
[root@oldboy83-prod oldboy]# egrep '0+' re.txt
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]# egrep -o '0+' re.txt
000
00000
- 取出连续出现的数字
[root@oldboy83-prod oldboy]# egrep '[0-9]+' re.txt
my blog is http://oldboy.blog.51cto.com
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]# egrep -o '[0-9]+' re.txt
51
49000448
4900000448
[root@oldboy83-prod oldboy]#
[root@oldboy83-prod oldboy]# egrep '[a-Z]' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY![root@oldboy83-prod oldboy]# egrep -o '[a-Z]+' re.txt
I
am
oldboy
teacher
I
teach
linux
I
like
badminton
ball
billiard
ball
and
chinese
chess
my
blog
is
http
2)| 或者一般用于单词或者.
- 文件中包含 oldboy 或 linux 的行
[root@oldboy83-prod oldboy]# egrep 'oldboy|linux' re.txt
I am oldboy teacher!
I teach linux.
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
[root@oldboy83-prod oldboy]# egrep '[oldboylinux]' re.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our size is http://blog.oldboyedu.com
my qq is 49000448
not 4900000448.
my god ,i am not oldbey,but OLDBOY!
- 在 /etc/services 过滤出包含 ssh 或 http 或 smtp 的行
[root@oldboy83-prod oldboy]# egrep 'ssh|http|smtp' /etc/services
# http://www.iana.org/assignments/port-numbers
ssh 22/tcp # The Secure Shell (SSH) Protocol
ssh 22/udp # The Secure Shell (SSH) Protocol
smtp 25/tcp mail # Simple Mail Transfer Protocol
smtp 25/udp mail # Simple Mail Transfer Protocol
http 80/tcp www www-http # WorldWideWeb HTTP
http 80/udp www www-http # HyperText Transfer Protocol
http 80/sctp # HyperText Transfer Protocol
https 443/tcp # http protocol over TLS/SSL
https 443/udp # http protocol over TLS/SSL
https 443/sctp # http protocol over TLS/SSL
gss-http 488/tcp
- 排除 /etc/ssh/sshd_config 中的空行或注释,输出的时候显示行号
grep -v '^$' /etc/ssh/sshd_config |grep -v '^#'
egrep -vn '^$|^#' /etc/ssh/sshd_config
#一些配置文件中有空行,以#开头的行,不带注释的正常的行以字母开头的行.
正常的配置的行,以字母开头的行.
grep '^[a-Z]' /etc/ssh/sshd_config
[root@oldboy83-prod oldboy]# egrep -vn '^$|^#' /etc/ssh/sshd_config
22:HostKey /etc/ssh/ssh_host_rsa_key
24:HostKey /etc/ssh/ssh_host_ecdsa_key
25:HostKey /etc/ssh/ssh_host_ed25519_key
32:SyslogFacility AUTHPRIV
47:AuthorizedKeysFile .ssh/authorized_keys
65:PasswordAuthentication yes
69:ChallengeResponseAuthentication no
79:GSSAPIAuthentication yes
80:GSSAPICleanupCredentials no
96:UsePAM yes
101:X11Forwarding yes
126:AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
127:AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
128:AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
129:AcceptEnv XMODIFIERS
132:Subsystem sftp /usr/libexec/openssh/sftp-server
3)()表示一个整体,用于后向引用(反向引用 sed)
一般用于表示整体或在 sed 命令中实现后向引用。
- 检查系统中 tree,vim,sl 软件是否安装。
[root@oldboy-85-vip-king-v2 oldboy]# rpm -qa |egrep '^tree|^vim|^sl'
vim-minimal-7.4.629-7.el7.x86_64
vim-filesystem-7.4.629-8.el7_9.x86_64
tree-1.6.0-10.el7.x86_64
vim-common-7.4.629-8.el7_9.x86_64
vim-enhanced-7.4.629-8.el7_9.x86_64
slang-2.2.4-11.el7.x86_64
sl-5.02-1.el7.x86_64[root@oldboy-85-vip-king-v2 oldboy]# rpm -qa |egrep '^(tree|vim|sl)'
vim-minimal-7.4.629-7.el7.x86_64
vim-filesystem-7.4.629-8.el7_9.x86_64
tree-1.6.0-10.el7.x86_64
vim-common-7.4.629-8.el7_9.x86_64
vim-enhanced-7.4.629-8.el7_9.x86_64
slang-2.2.4-11.el7.x86_64
sl-5.02-1.el7.x86_64[root@oldboy-85-vip-king-v2 oldboy]# rpm -qa |egrep 'tree|vim|sl'
vim-minimal-7.4.629-7.el7.x86_64
cyrus-sasl-lib-2.1.26-23.el7.x86_64
vim-filesystem-7.4.629-8.el7_9.x86_64
xmlsec1-openssl-1.2.20-7.el7_4.x86_64
libxslt-1.1.28-6.el7.x86_64
python-slip-dbus-0.4.0-4.el7.noarch
openssl-1.0.2k-19.el7.x86_64
rsyslog-8.24.0-55.el7.x86_64
tree-1.6.0-10.el7.x86_64
vim-common-7.4.629-8.el7_9.x86_64
vim-enhanced-7.4.629-8.el7_9.x86_64
slang-2.2.4-11.el7.x86_64
openssl098e-0.9.8e-29.el7.centos.3.x86_64
openssl-libs-1.0.2k-19.el7.x86_64
sl-5.02-1.el7.x86_64
python-slip-0.4.0-4.el7.noarch
4){} a {n,m} 前一个字符连续出现至少 n 次,最多 m 次
使用频率不高,可以通过 {} 精确控制出现次数。
格式 | 含义 | 应用 |
---|---|---|
a | 前一个字符连续出现至少 n 次,最多 m 次 | 表示连续出现的范围 |
a | 前一个字符连续出现 n 次 | 匹配固定的次数 |
a | 前一个字符连续出现至少 n 次 | |
a | 前一个字符连续出现,最多 m 次 |
[root@oldboy83-prod oldboy]# egrep '0{1,5}' re.txt
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]# egrep -o '0{1,5}' re.txt
000
00000
[root@oldboy83-prod oldboy]# egrep '0{3,4}' re.txt
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]# egrep '0{3}' re.txt
my qq is 49000448
not 4900000448.
[root@oldboy83-prod oldboy]#
- 匹配身份证的正则
分析规律:前 17 位必须都是数字
第 18 位可以是数字或 X
整个身份证号码位于行的末尾
[root@oldboy83-prod oldboy]# cat id2.txt
谈媚轩 230189199012251659
庾菲刚 230181199012015108
桑春 23018215507074953
范惠融 230182197510240695
霍莎 23018219590413055X
单燕可 230182197007233320
雷聪 23018215709180586
郑芬澜 23018199402088233
阙宁茜 230182198305100379
赵璧桂 23018195312204747
史勤 23018218107207651
项珠 230182195305221943
季艳盛 230182195604045725
吕进 230182196412284021
翟竹静 230182196102271858
翟竹静 23018219610227
翟竹静 2301821922
翟竹静 230181922
[root@oldboy83-prod oldboy]# egrep '[0-9]{17}[0-9X]$' id2.txt
谈媚轩 230189199012251659
范惠融 230182197510240695
霍莎 23018219590413055X
单燕可 230182197007233320
阙宁茜 230182198305100379
项珠 230182195305221943
季艳盛 230182195604045725
吕进 230182196412284021
翟竹静 230182196102271858
- 匹配 ip 的正则
#创建环境
echo 10.0.0.{1..254} |xargs -n1 > ip.txt
#正则匹配
egrep '[0-9]{1,3}$' ip.txt
稍微复杂的匹配身份证的正则
地区: [1-9]\d{5}年的前两位: (18|19|([23]\d)) 1800-2399年的后两位: \d{2}月份: ((0[1-9])|(10|11|12))天数: (([0-2][1-9])|10|20|30|31) 闰年不能禁止 29+三位顺序码: \d{3}两位顺序码: \d{2}校验码: [0-9xx]正则表达式十八位: ^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$十五位: ^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$总:(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$)
5)? 前一个字符 出现 0 次或 1 次
使用较少。一般用于匹配的内容可能有(出现 1 次)或者没有出现(出现 0 次)。
[root@oldboy83-prod oldboy]# cat good.txt
gd
goood
god
good
gooood
[root@oldboy83-prod oldboy]# egrep 'gd|god' good.txt
gd
god
[root@oldboy83-prod oldboy]# egrep 'go?d' good.txt
gd
god
[root@oldboy83-prod oldboy]# egrep 'go+d' good.txt
good
god
good
gooood
[root@oldboy83-prod oldboy]# egrep 'go*d' good.txt
gd
good
god
good
gooood
[root@oldboy83-prod oldboy]# egrep 'go{1,2}d' good.txt
god
good
[root@oldboy83-prod oldboy]# egrep 'go{,2}d' good.txt
gd
god
good
6)扩展正则小结
扩展正则 | 含义 |
---|---|
+ ☆☆☆☆☆ | 前一个字符连续出现 1 次或多次 |
| ☆☆☆☆☆ | 或者 |
() ☆☆ | A 表示整体 B 后向引用或反向引用(sed) |
{} | a {n,m} 前一个字符连续出现至少 n 次,最多 m 次 |
? | 前一个字符出现 0 次或 1 次 |