正则表达式介绍
什么是正则表达式
- 以特定的符号表示一组数字或字母的,一种规则。

为何需要正则表达式
- 在工作中,我们时刻面对着大量的日志、程序以及命令的输出。迫切的需要过滤我们需要的一部分内容,甚至是一个字符串
- 比如:现在有一个上千行的文件,我们仅需要其中包含
error的行,怎么办?此时就需要使用到正则表达式的规则来筛选想要的内容
正则表达式注意事项
- 1.正则表达式应用非常广泛,存在于各种编程语言中
- 2.正则表达式和
linux的通配符以及特殊字符是有区别的 - 3.想要学好
grep、sed、awk首先就需要对正则表达式有一定的了解。只有了解了规则,才能灵活的运用。
正则表达式规则语法
-
正则表达式:
\:转义符,将特殊字符进行转义,忽略其特殊意义^:匹配行首,匹配字符串的开始$:匹配行尾,匹配字符串的结尾^$:表示空行.:匹配除换行符\n之外的任意单个字符[]:匹配包含在[字符]之中的任意一个字符[a|b]cd[^]:匹配[^a]之外的任意字符[ - ]:匹配[]中指定范围内的任意一个字符[a-z][0-9]?:匹配之前的项1次或者0次+:匹配之前的项1次或者多次[0-9]+*:匹配之前的项0次或者多次.*():匹配表达式,创建一个用户匹配的子串grep "ab(c|d)"{n}:匹配之前的项n次,n可以为0的正整数grep "[0-9]{1,3}"{n,}:之前的项至少需要匹配n次{n,m}:之前的项至少匹配n次,最多匹配m次,n<=m|:交替匹配,|两边的任意一项匹配ab(c|d)\<\>:锚定词首与词尾,\<grep\>,匹配所有包含grep字符的行,如果出现grepa是不会被匹配
-
特殊字符:
[[:space:]]:匹配空格[[:digit:]]:匹配[0-9][[:lower:]]:匹配[a-z][[:upper:]]:匹配[A-Z][[:alpha:]]:匹配[a-Z]
-
准备如下文件,然后进行正则表达式规则验证
I am a teacher!
I teach linux .
test
I like badminton ball ,billiard ball and chinese chess!
my blog is
http://blue.yn.cn
our site is http://blue.yn.cn
my qq num is 572891887 .
not 572891888887 .
- 进行如下场景验证:
- 1.过滤以
m开头的行grep '^m' grep.txt my blog is my qq num is 572891887 . - 2.排除空行,并打印行号
grep -vn '^$' grep.txt 1:I am a teacher! 2:I teach linux . 3:test 5:I like badminton ball ,billiard ball and chinese chess! 6:my blog is 7:http://blue.yn.cn 8:our site is http://blue.yn.cn 9:my qq num is 572891887 . 10:not 572891888887 . - 3.匹配任意一个字符,不包括空行
grep '.' grep.txt I am a teacher! I teach linux . test I like badminton ball ,billiard ball and chinese chess! my blog is http://blue.yn.cn our site is http://blue.yn.cn my qq num is 572891887 . not 572891888887 . - 4.匹配所有内容
grep -n '.*' grep.txt [root@manager grep]# grep -n '.*' grep.txt 1:I am a teacher! 2:I teach linux . 3:test 4: 5:I like badminton ball ,billiard ball and chinese chess! 6:my blog is 7:http://blue.yn.cn 8:our site is http://blue.yn.cn 9:my qq num is 572891887 . 10:not 572891888887 . 11: - 5.匹配以点结尾的
grep '\.$' grep.txt I teach inux . my qq num is 572891887 . not 572891888887 . - 6.匹配有
a或b或c的行grep '[a|b|c]' grep.txt I am a teacher! I teach linux . I like badminton ball ,billiard ball and chinese chess! my blog is http://blue.yn.cn our site is http://blue.yn.cn - 7.匹配数字所在的行
egrep '[0-9]+' grep.txt my qq num is 572891887 . not 572891888887 . - 8.匹配所有小写字母所在的行
grep '[a-z]' grep.txt I am a teacher! I teach linux . test I like badminton ball ,billiard ball and chinese chess! my blog is http://blue.yn.cn our site is http://blue.yn.cn my qq num is 572891887 . not 572891888887 . - 9.匹配包含5个8的行
egrep '[8]{5}' grep.txt not 572891888887 .
- 1.过滤以
正则表达式案例
过滤掉空行与#开头的行
- 需求:使用
grep正则表达式方式,排除nginx配置文件的以一个或多个空格+#开始的行,以#开始的行,和空行
egrep -v "[[:space:]]+#|^#|^$" /etc/nginx/nginx.conf
提取服务器网卡地址
- 需求:使用
grep正则表达式方式,提取服务器eth0网卡配置的ip地址
ifconfig eth0 | grep 'inet ' | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1
匹配日志中http版本
- 需求:使用
grep正则表达式方式,匹配nginx日志中的http3.0 http3.1 http2.1 http2.0 http1.1 http1.0
egrep -o "HTTP/(1|2|3)\.(0|1)" /var/log/nginx/access.log | sort | uniq -c
过滤掉注释的配置文件
- 需求:使用
grep正则表达式方式,匹配zabbix_agent2.conf配置文件中素有已启用的配置
egrep -v "^#|^$" /etc/zabbix/zabbix_agent2.conf
egrep "^[a-Z]" /etc/zabbix/zabbix_agent2.conf
匹配用户手机号是否合法
- 需求:使用
grep正则表达式方式,匹配133、153、189、199开头的手机号码
cat phone.sh
#!/usr/bin/bash
read -p "请输入你的手机号码以 [ 133 | 153 | 189 | 199 ] 开头:" Action
if [[ $Action =~ ^[0-9]{11} ]];then
if [[ $Action =~ ^(133|153|189|199)[0-9]{8}$ ]];then
echo "$Action 手机号通过"
else
echo "$Action 手机号不是电信手机号..."
fi
else
echo "你的手机号是 ${#Action} 位,不满足要求..."
fi
匹配用户邮箱是否合法
- 需求:使用
grep正则表达式方式,匹配qq、163、sina的email地址
cat email.sh
#!/usr/bin/bash
read -p "请输入找回密码的邮箱:" Action
Action_pre=${Action%@*}
if [ ${#Action_pre} -gt 16 ];then
echo "你输入的邮箱前缀长度超过16位"
exit
fi
if [[ $Action =~ ^([0-9]|[a-Z])+@(qq|163|sina)\..+$ ]];then
echo "$Action 邮件已经发送,请登录邮箱点击链接找回密码"
else
echo "$Action 不符合系统预定的邮箱规则,请重新尝试"
fi
匹配文件中的域名
cat rege.txt
xxt-demo.shop.oldxu.com
xxt-demoadmin.shop.oldxu.com
abc.shop.oldxu.com
abcadmin.shop.oldxu.com
123.shop.oldxu.com
abc123.shop.oldxu.com
admin123.shop.oldxu.com
egrep "^([a-z]+-[a-z]+|[a-z]+|admin123)\.shop.oldxu.com" rege.txt
sed文本处理
sed基本介绍
sed(stream editor)流编辑器,能够对标准输出或文件进行逐行处理
简单来说,sed可以实现对文件的增、删、查、改
sed工作模式
sed读取文件一行,存放在缓存区,然后处理,最后输出
sed基础语法
- 第一种形式:
stdout | sed [option] "pattern command" - 第二种形式:
sed [option] "pattern command" file
sed常用选项
| 选项 | 含义 |
|---|---|
| -n | 只打印匹配的行(取消文件的默认输出) |
| -e | 允许多项编辑 |
| -f | 编辑动作保存在文件,指定文件才执行 |
| -r | 支持扩展正则表达式 |
| -i | 直接变更文件内容 |
-n选项
sed -n用于取消默认输出
sed -n '/^root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
-e选项
sed -e用于多项编辑
sed -n -e '/^root/p' -e '/^chrony/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
sed -n -r '/^root|^chrony/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
-f选项
sed -f编辑动作保存在文件,指定文件才执行
将pattern写入文件中
cat edit.sed
/^root|^chrony/p
通过sed -f执行
sed -nrf edit.sed /etc/passwd
root:x:0:0:root:/root:/bin/bash
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
-r选项
sed -r支持扩展正则表达式
ifconfig eth0 | sed -n '/inet /p' | sed -r 's#(^.*et) (.*) (net.*$)#\2#g'
192.168.99.7
sed pattern过滤
- 命令格式:
sed [option] '/pattern/command' file
pattern命令格式
| 匹配模式 | 含义 |
|---|---|
| 10command | 匹配第10行 |
| 10,20command | 匹配从第10行开始,到第20行结束 |
| 10,+5command | 匹配从第10行开始,到第15行结束 |
| /pattern1/,/pattern2/command | 匹配到pattern1的行开始,到匹配到pattern2的行结束 |
| 10,/pattern1/command | 匹配从第10行开始,到匹配到pattern1的行结束 |
pattern命令示例
-
示例1:指定行号
# 打印passwd文件的第10行 sed -n '10p' /etc/passwd operator:x:11:0:operator:/root:/sbin/nologin -
示例2:指定起始行号和结束行号
# 打印passwd文件的10到20行 sed -n '10,20p' /etc/passwd -
示例3:指定起始行号,然后加
N行# 打印passwd文件中从第1行开始,往后面加5行的内容 sed -n '1,+5p' /etc/passwd -
示例4:正则表达式匹配(打印
passwd文件中以root开头的行)sed -n '/^root/p' /etc/passwd root:x:0:0:root:/root:/bin/bash -
示例5:从匹配到
pattern1的行,到匹配pattern2的行(打印passwd文件第一个匹配到以bin开头的行,到第二个匹配到以ftp开头的行
sed -n '/^bin/,/^ftp/p' /etc/passwd -
示例6:从指定的行号开始匹配,直到匹配到
pattern1的行# 打印passwd文件中从第2行开始匹配,直到以sync开头的行结束 sed -n '2,/^sync/p' /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync
sed追加命令
追加命令格式
| 编辑命令 | 含义 |
|---|---|
| a | 行后面追加内容append |
| i | 行前追加内容insert |
| r | 读入外部文件,行后追加 |
| w | 将匹配行写入外部文件 |
-
示例1:匹配
/bin开始的行,在其后面添加内容
sed -i '/^bin/a OKOK\nKOKO' passwd -
示例2:以
/nobody开头的行到以sshd开头的行,前面添加内容
sed -i '/^nobody/,/^sshd/i OK-AAA-OK' passwd -
示例3:更改
ssh端口
sed -i '/#Port/i Port 666' /etc/ssh/sshd_config -
示例4:给文件的第6行前面添加内容
sed -i '6i hello world' passwd -
示例5:将
edit.sed文件中的内容,追加到匹配模式的行后面
sed -i '/^root/r edit.sed' passwd -
示例6:匹配
/bin/bash所有的行,将其保存至login.txt文件中sed -n '/\/bin\/bash/w login.txt' passwd cat login.txt root:x:0:0:root:/root:/bin/bash www:x:666:666::/home/www:/bin/bash -
示例7:
passwd文件每一行前面都追加hello world
sed -i '/^/i hello world' passwd
sed删除命令
删除命令格式
| 编辑命令 | 含义 |
|---|---|
| 1d | 删除第1行的内容 |
| 1,5d | 删除第1行到第5行的内容 |
| 2,+5d | 删除第2行以及往下5行的内容 |
| /pattern1/d | 删除每行中匹配到pattern1的行内容 |
| /pattern1/,/pattern2/d | 删除匹配pattern1的行直到匹配到pattern2的行的所有内容 |
| /pattern1/,10d | 删除匹配pattern1的行到第10行的所有内容 |
| 10,/pattern1/d | 删除第10行直到匹配到pattern1的所有内容 |
删除命令示例
-
示例1:删除
passwd文件中第1行的内容
sed -i '1d' passwd -
示例2:删除
passwd文件中第1行到第5行的内容
sed -i '1,5d passwd -
示例3:删除
passwd文件中第2行以及往下5行的内容
sed -i '2,+5d passwd -
示例4:匹配
/sbin/nologin结尾的行,然后进行删除
sed -i '/\/sbin\/nologin$/d' passwd -
示例5:删除匹配以
sshd开头的行,到rpc开头的行
sed -i '/^sshd/,/^rpc/d' passwd -
示例6:找到配置文件中注释的行以及空行
1.以#号开头的行
sed -n '/^#/p' test.txt
# nihao
####nihao
2.以空格+#号或者#开头的行
sed -rn '/^ *#/p' test.txt
#hello o
# nihao
####nihao
####
3.空行
sed -n '/^$/p' test.txt
4.以tab键或空格开头+#开头的行
sed -n '/^[ |\t]*#/p' test.txt
#hello o
# nihao
####nihao
####
#if
#else
5.最后合成一句删掉注释的行
sed -r '/^[ |\t]*#|^$/d' test.txt
sed -ri '/^[ \t]*#|^$/d' test.txt
123
abc
sed修改命令
修改命令格式
| 编辑命令 | 含义 |
|---|---|
| 1s/old/new/ | 替换第1行内容old为new |
| 1,10s/old/new/ | 替换第1行到第10行的内容old为new |
| 1,+5s/old/new/ | 替换第1行到第6行的内容old为new |
| /pattern1/s/old/new/ | 替换匹配pattern1的内容old为new |
| /pattern1/,/pattern2/s/old/new/ | 替换匹配pattern1的行直到匹配到pattern2的所有行内容old为new |
| 10,/pattern1/s/old/new/ | 替换第10行直到匹配到pattern1的所有行内容old为new |
修改命令示例
-
示例1:使用
sed提取eth0网卡的ip地址ifconfig eth0 | sed -rn '2s#(^.*net) (.*) (net.*$)#\2#p' 192.168.99.7 ifconfig eth0 | sed -n '/net /p' | sed -r 's#(^.*net) (.*) (net.*$)#\2#' 192.168.99.7 -
示例2:修改
passwd文件第1行中第一个root为ROOT(g为全局/全部替换)
sed -i '1s/root/ROOT/' passwd
sed -i '1s/root/ROOT/g' passwd -
示例3:将
passwd文件所有行前面添加注释
sed -n 's/^/# /p' passwd -
示例4:修改
passwd文件中第5行到第10行中所有的/sbin/nologin为/bin/bash
sed -n '5,10s#/sbin/nologin#/bin/bash#p' passwd -
示例5:修改
SELINUX=enforce为SELINUX=disabled(可以使用c替换方式)
sed -i '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config
留言