内容目录

正则表达式介绍

什么是正则表达式

  • 以特定的符号表示一组数字或字母的,一种规则。

file

为何需要正则表达式

  • 在工作中,我们时刻面对着大量的日志、程序以及命令的输出。迫切的需要过滤我们需要的一部分内容,甚至是一个字符串
  • 比如:现在有一个上千行的文件,我们仅需要其中包含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.匹配有abc的行
      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 .

正则表达式案例

过滤掉空行与#开头的行

  • 需求:使用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、sinaemail地址
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行中第一个rootROOT (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=enforceSELINUX=disabled(可以使用c替换方式)
    sed -i '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config

最后修改日期: 2024年12月16日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。