正则表达式介绍
什么是正则表达式
- 以特定的符号表示一组数字或字母的,一种规则。
为何需要正则表达式
- 在工作中,我们时刻面对着大量的日志、程序以及命令的输出。迫切的需要过滤我们需要的一部分内容,甚至是一个字符串
- 比如:现在有一个上千行的文件,我们仅需要其中包含
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
留言