什么是正则表达式
正则表达式是为处理大量文本及字符串而定义的一套规则和方法
好多语言都支持正则表达式,语法规则大同小异,linux中支持的正则表达式比较简单,我们本次只讨论linux中的正则表达式,下文提到的正则表达式没有特殊说明,都指linux下的正则表达式
正则表达式特点
- 其工作以行为单位进行,即一次处理一行
- 使用正则表达式可以将复杂任务简单化,提高效率
- linux中只有grep sed awk命令支持正则表达式 其他命令不支持
注意:只有 grep sed awk命令支持正则表达式 其他命令支持通配符,
关于通配符的文章见 linux通配符与特殊符号
# 注意这里的*.txt ip.*都是通配符而不是正则
[root@centos76 data]# ls /root/data/*.txt
[root@centos76 data]# find /root/ -name ip.*
/root/data/ip.txt
linux中正则的元字符分类两类
- 基础正则
^
$
.
\
*
[
]
- 扩展正则
(
)
{
}
?
+
|
实验环境
ip.txt 内容
a-^b$c.\
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.9
基础正则
grep命令
grep命令是用来根据规则过滤出文件中符合规则的行
格式: grep 选项 正则 文件
^
表示以什么开头的行
# 过滤出以192开头的行
[root@centos76 data]# grep "^192" ip.txt
a-^b$c.\
192.168.1.5
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
$
表示以什么结尾的行
# 过滤出以88结尾的行
[root@centos76 data]# grep "88$" ip.txt
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
^$
匹配空行
[root@centos76 data]# grep "^$" ip.txt
[root@centos76 data]#
.
表示任意一个字符 且只有一个字符
不能匹配空行
# 发现除了空行所有字符都被匹配上了
# 自己一定要在自己的环境上试一下 才能更好的看出来效果
[root@centos76 data]# grep "." ip.txt
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.9
\
表示转义
如果我就想匹配 .
本身 而不是匹配任意一个字符呢
也就是让有特殊含义的.
不再表示特殊含义 而是表示一个字符.
这时候就用到转义字符了 \.
这表示字符.
[root@centos76 data]# grep "\." ip.txt
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.9
*
表次数 *
前一个字符出现0次或0次以上
注意和linux通配符与特殊符号中*
的区别
# 注意有一个8 有两个8的行都匹配出来了 没有8的行也匹配出来了 因为8出现0次也符合规则
[root@centos76 data]# grep "8*" ip.txt
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.9
[]
匹配 []
中的任意一个字符
-
[abcd]
只要含有a b c d任意一个都能匹配 -
[a-z]
表示a到z中的任意一个字符都能匹配 这里-表示范围 -
[^abcd]
表示除了abcd这几个字符其他字符都能匹配 这里^表示取反 -
[.$]
表示匹配.
或者$
注意在[]
中的某些字符不需要转义 就表示字符本身- 思考下
^
和-
在[]
中有特殊含义 如果就想匹配这两个字符呢,也有办法把他们位置打乱就行了
- 思考下
# ^没放到开头 所以不再表示取反 就表示自己
# - 没放到连个字符之间 所以不再表示范围 就表示自己
# 此时 [] 之间的五个字符都没有特殊含义
[root@centos76 data]# grep "[-\.^$]" ip.txt
a-^b$c.\
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.9
扩展正则
注意:grep命令默认只支持基础正则 要这只扩展正则 需要加 -E参数
grep -E
也可以写 egrep
两者等效
+
表次数 +前一个字符出现1次或多次 最少一次
# 这一次不包含8的行就过滤不出来了
[root@centos76 data]# egrep "8+" ip.txt
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
?
表次数 ?前一个字符出现0次或者1次
注意和linux通配符与特殊符号中?的区别
{
}
表次数
- {m} m次
- {m,n} 最少m次最多n次
- {m,} 最少m次
# 自己在环境中敲一下 能看到匹配的详情 有颜色 这里看不出来
[root@centos76 data]# egrep "[0-9]{1,3}" ip.txt
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.9
|
表示或者
# 192开头的 或者10开头的
[root@centos76 data]# egrep "^192|^10" ip.txt
192.168.1.5
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
192.168.1.20
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.88
10.10.0.9
(
)
用来分组 分组后可以引用
# 过滤 以10开头并且10结尾的行 .表示任意字符 *表示任意数量
# ^10.*10$
[root@centos76 data]# egrep "^10.*10$" ip.txt
10.10.0.10
前面10和后面10是一样的 这时就可以用分组了
# ()引起来的内容作为分组 可以在之后引用 后面的\1表示第一个分组在这里就是10
# 所以这个命令和上面的效果一样
# 如果有多个分组就是\1 \2 \3以此类推
[root@centos76 data]# egrep "^(10).*\1$" ip.txt
10.10.0.10