shell实战正则表达式

发布时间 2023-12-15 14:08:58作者: WeChat2834
正则表达式
  • 匹配有规律的东西:手机号,身份证号,匹配日志什么
  • 正则表达式 ,regular expression(RE)
  • 正则:使用一些符号表达重复出现,大小写,开头/结尾含义。

应用场景

哪些可以正则表达式 Linux三剑客使用,一些开发语言
应用场景 过滤有规律的内容,尤其是日志
正则符号
分类
基础正则 BRE ^ $ ^$ . * .* [a-z] [^abc]
扩展正则 ERE + | () {} ?
per语言中的正则(高档局了)
正则VS通配符
分类 诞生目标(用途) 支持的命令
正则(re) 三剑客,高级语言,进行过滤(匹配字符) 三剑客 grep,sed ,awk ,find,rename(ubuntu),expr
通配符(pathname extension 或glob) 匹配文件(文件名)*.txt *.log Linux下面大部分命令都支持
^以....开头的行
  • ^s 以s开头的行
[root@localhost shell_rpo]# grep '^r' test_andor4.sh 
read num
[root@localhost shell_rpo]# grep '^s' test_andor4.sh 
set -x
set +x
[root@localhost shell_rpo]# alias 
$ 以......结尾的行
[root@localhost shell_rpo]# grep  -n '4$' test_andor4.sh 
82:	exit 4
[root@localhost shell_rpo]# 
#######找1结尾的数据,查询为空
[root@localhost shell_rpo]# grep  -n '1$' test_andor4.sh 
[root@localhost shell_rpo]#
[root@localhost shell_rpo]# cat -A  -n test_andor4.sh     ###-A显示隐藏标记$
[root@localhost shell_rpo]# cat -A  -n test_andor4.sh 
     1	#!/bin/bash$
     2	$
     3	###M-fM- M-9M-fM-^MM-.M-iM-^@M-^IM-iM-!M-9M-eM-.M-^IM-hM-#M-^ElnmpM-hM-?M-^XM-fM-^XM-/lampM-oM-<M-
     ......
    46	^Iexit 1 $  #####会发现$隐藏的结尾标记之间有个空格
      ......
    78	$
    79	[[ ! "$num" =~ [1-3] ]]&&{$
    80	$
    81	^Iecho "M-eM-^OM-*M-hM-^CM-=M-eM-=M-^UM-eM-^EM-%M-iM-^@M-^IM-iM-!M-9{1|2|3}"$
    82	^Iexit 4$
    83	}$
[root@localhost shell_rpo]# 
[root@localhost shell_rpo]# grep  -n '1 $' test_andor4.sh 
46:	exit 1 
[root@localhost shell_rpo]# 



^$ 空行
  • 空行这一行中,没有任何内容,(空格也是符号)
  • 空格也是字符
[root@localhost shell_rpo]# grep  -n '^$' test_andor4.sh 
2:
4:
8:
10:
12:
18:
[root@localhost shell_rpo]# 

企业级的应用一般是**排除空行 grep -v '^$' **

[root@localhost shell_rpo]# grep  -v '^$' test_andor4.sh 
#!/bin/bash
###根据选项安装lnmp还是lamp;录入选项限制1,2,3;
path=/root/tmp/Instal
#条件判断,判断目录是否存在,
#开发脚本,真和假两个情况,优先处理错误的逻辑情况,因为错误的情况最容易处理
[ ! -d "${path}" ]&& mkdir "${path}" -p
#开发该脚本的正常逻辑了
cat << END
       1. [install  lamp]
       2. [install  lnmp]
       3. [exit]
      please input the number you want!
END
###接收用户输入
read num
#根据该num变量进行逻辑处理
expr $num + 1 &>/dev/null             ##
..............
.(点)表示任意一个字符
  • 注意,点不匹配符号
\转义字符 去除原又特殊含义
  • 例如匹配以点结尾的行 grep '\.$' XXX.txt
  • 转义字符序列
    • \n 回车换行
    • \t tab键
*表示前一个字符连续出现0次或0次以上
  • 连续出现: 0(0出现1次), 00 (0出现2次)
.*(点星)所有内容,任何内容,任意内容
  • 正则特色:正则表达式的贪婪性,.*表示所有或*连续出现的时候,表现尽可能的多的匹配
[root@localhost shell_rpo]# grep '.*s'  /etc/init.d/functions 
###理想状态是每行匹配到第一个s结尾就结束,实际上会匹配到行所有的s才会结束
正则表达式的那些事儿
  1. 灵异的 2* 和0*
###没有0的行也展示出来了
[root@localhost tmp]# grep '0*' test01.sh 
#!/bin/bash

namess='Mrxu'
days=10
echo "${namess} 已经学习了${days}天"
###没有2的行也展示出来了
[root@localhost tmp]# grep '2*' test01.sh 
#!/bin/bash

namess='Mrxu'
days=10
echo "${namess} 已经学习了${days}天"
[root@localhost tmp]# 

因为*表示出现0次货0次以上

[] [abc] 1次匹配一个字符,匹配任何一个字符(a或b或c)

[] 只匹配一个字符

一般写法

  • [a-z]
  • [A-Z]
  • [0-9]
  • 匹配文件中的大小写字母和数字
    • [a-zA-Z](一般没啥问题)==[a-Z](可能出现字符集类的问题要调整)
  • 注意[a-z|A-Z]匹配了大小写字母还有|;当然空格,等其他符号都也会类似的匹配出来
[root@localhost tmp]# grep '[abc]' test01.sh 
#!/bin/bash
namess='Mrxu'
days=10
echo "${namess} 已经学习了${days}天"
[root@localhost tmp]# grep -no '[abc]' test01.sh
1:b
1:b
1:a
3:a
4:a
5:c
5:a
5:a
[root@localhost tmp]# 
[root@localhost tmp]#   -o表示展示匹配过程
[root@localhost tmp]# grep -no '[abc]' test01.sh |wc -l
8
####加个统计能筛选出现的次数了哈哈‘
[^] 取反 [^abc] 排除abc以外的

中括号里加上^表示排除

扩展正则

注意扩展正则,grep不能直接使用需要 -E选项 或者egrep可直接使用

  • grep -E
  • egrep
符号 含义 搭配场景
+ 前一个字符出现1次货1次以上
| 或者
() 一个整体,sed反向引用
{} o{n,m} ,o连续出现至少n次,至多m次
? 前一个字符连续出现0次或1次
+ 号 前一个字符出现1次或1次以上
[root@localhost tmp]# seq 1 30 |xargs  -n3>rre.sh
[root@localhost tmp]# ll
[root@localhost tmp]# grep  '1+' rre.sh 
[root@localhost tmp]#  #直接grep没用不支持扩展正则
[root@localhost tmp]# grep  -E '1+' rre.sh 
1 2 3
10 11 12
13 14 15
16 17 18
19 20 21
[root@localhost tmp]# egrep  '1+' rre.sh 
1 2 3
10 11 12
13 14 15
16 17 18
19 20 21
[root@localhost tmp]# 
[root@localhost tmp]# grep  '1\+' rre.sh 
1 2 3
10 11 12
13 14 15
16 17 18
19 20 21
[root@localhost tmp]#  加上转义\也行但是不知道为啥,不推荐这个写法
  • 匹配文件中的连续数字
  • 匹配文件中的单词,就是连续字母哈哈
| 符号 或者

注意 与[]的区别

符号 应用场景
[] [mrxx]一次匹配其中的一个字符 匹配单个字符[]和+经常一起使用
| 匹配一个字符或多个字符;a|b|c mrxx|mixSS 匹配单词的时候
()表示被括起来的内容,表示一个整体 后向引用(反向引用sed)
  • 被括起来的内容,表示一个整体(一个字符串)
  • 后向引用(反向引用sed)
[root@localhost tmp]#  egrep  '(if|fi)' /etc/init.d/functions 
# functions This file contains functions to be used by most or all
if [ $PPID -ne 1 -a -z "$SYSTEMCTL_SKIP_REDIRECT" ] && \
fi
        s=$"Reloading $prog configuration (via systemctl): "
    if [ -n "$SYSTEMCTL_IGNORE_DEPENDENCIES" ] ; then
    fi
    if ! systemctl show "$prog.service" > /dev/null 2>&1 || \
    fi
if [ -z "${CONSOLETYPE:-}" ]; then
    if [ -c "/dev/stderr" -a -r "/dev/stderr" ]; then
    fi
...............
{} 连续出现 o{n,m},前一个字母o,至少连续出现n次,最多连续出现m次
符号
o 前一个字母o,至少连续出现n次,最多连续出现m次 >=n,<=m
o 前一个字母o,连续出现n次 ==n
o 前一个字母o,至少连续出现n次 >=n
o 前一个字母o,最多连续出现m次 <=m
? 连续出现,前一个字符出现0次或1次
[root@localhost re]# egrep  'gd|god' test01.sh 
god
gd
[root@localhost re]# egrep  'go?d' test01.sh 
god
gd
[root@localhost re]# [root@localhost re]# cat test01.sh 
goood
good
god
gd
[root@localhost re]#
案例
  1. 过滤出文件中符号要求的身份证号码
  2. .排除文件中的空行或含有#号的行
#.1
[root@localhost myfunction]# egrep '[0-9]{17}[0-9x]'
#.2
[root@localhost myfunction]# egrep -v '(^$|#+)' myfunctiontest3.sh 

注意事项
  • 所有的符号都是英文符号

  • 学习正则,通过grep命令学习,grep加上单引号

  • 给grep,egrep加上颜色 alias grep='grep --color=auto' alias egrep='egrep --color=auto'

  • 注意系统的字符集:en_US.UTF-8(大部分情况没问题),如果出现问修改字符集为C exportlang=C

  • 快速掌握正则:需配置grep -o 参数学习。

  • cat -A显示隐藏标记$;可以查看是否已空格结尾了