1、正则表达式说明

正则表达式和通配符的区别

  • 正则表达式用来在文件中匹配符合条件的字符串。
  • 通配符用来匹配符合条件的文件名。

在Shell中,使用在文件当中搜索字符串的命令,如grepawksed等命令(文本操作三剑客),可以支持正则表达式。

而在系统当中搜索文件的命令,如lsfindcp这些命令不支持正则表达式,所以只能使用通配符来进行匹配了。

  • 在Shell中只要是匹配字符串,都适用于正则匹配。
  • 正则表达式匹配的是以一行为单位进行包含匹配的,匹配上就显示输出该行文本,否则不显示。

2、基础正则表达式

元字符 作用
* 匹配前一个字符匹配0次或任意多次。
. 匹配除了换行符外任意一个字符。
^ 匹配行首。例如:^hello会匹配以hello开头的行。
$ 匹配行尾。例如:hello$会匹配以hello结尾的行。
[] 匹配中括号中指定的任意一个字符,只匹配一个字符。
例如:
[aoeiu]匹配意一个元音字母,
[0-9]匹配任意一位数字,
[a-z][0-9]匹配小写字和一位数字构成的两位字符。
[^] 匹配除中括号的字符以外的任意一个字符。
例如:
[^0-9]匹配任意一位非数字字符,
[^a-z]表示任意一位非小写字母。
\ 转义符。用于取消将特殊符号的含义取消。
\{n\} 表示其前面的字符恰好出现n次。
例如:
[0-9]\{4\}匹配4位数字,
[1][3-8][0-9]\{9\}匹配手机号码。
\{n,\} 表示其前面的字符出现不小于n次。
例如:
[0-9]\{2,\}表示两位及以上的数字。
\{n,m\} 表示其前面的字符至少出现n次,最多出现m次。
例如:
[a-z]\{6,8\}匹配6到8位的小写字母。

注意:Shell语言不是一个标准的完整语言,在其他语言中的正则表达式中,是不分基础正则和扩展正则的。而Shell认为你不需要拿正则写太过复杂的字符串筛选格式,所以Shell建议把正则表达式分成基础正则和扩展正则两种。

3、练习

(1)准备工作

创建一个测试文档test.txt

Seven times have I despised my soul:
——Kahlil Gibran The first time when I saw her being meek that she might attain height. The second time when I saw her limping before the crippled. The third time when she was given to choose between the hard and the easy, and she chose the easy. The fourth time when she committed a wrong, and comforted herself that others also commit wrong. The fifth time when she forbore for weakness, and attributed her patience to strength. The sixth time when she despised the ugliness of a face, and knew not that it was one of her own masks. And the seventh time when she sang a song of praise, and deemed it a virtue.

(内容为纪伯伦——我曾七次鄙视自己的灵魂)

还有,为了方便查看,我们可以给grep命令配置带有颜色输出,也就是给grep命令定义一个别名。

在当前用户家目录中的~/.bashrc文件中配置grep命令别名:

# 我们当前的用户是root用户
# 执行命令
[root@localhost ~]# vim /root/.bashrc # 添加内容
alias grep='grep --color=auto' # 或者
# 针对所有用户
# echo "alias grep='grep --color=auto'" >>/etc/bashrc
# 针对单个用户
# echo "alias grep='grep --color=auto'" >>~/.bashrc

这样在grep命令执行后的标准输出中,就会将文件中匹配的内容标识彩色。

注意:如果在XShell终端修改的~/.bashrc配置文件,需要关闭当前远程窗口,重新打开就可以实现了。

(2)*练习

我们执行如下命令,进行*匹配练习

[root@localhost tmp]# grep "k*" test.txt

结果如下:

说明:(重点)

任何字母加上*,或者说任何符号加上*,都没有任何含义,这样会匹配所有内容,包括空白行。

因为*的作用是重复前一个字符0次或任意多次。

所以在Shell中的正则中,任何符号加上*是没有任何含义的,所有的内容都会被匹配出来。

如果你需要匹配至少包含一个k字母的行,就需要这样写"kk*",代表匹配至少包含有一个K的行,也可以有多个k。(这行字符串一定要有一个k,但是后面有没有k都可以。)

如下图:

我们可以看到,没有k的行,和空行都被过滤掉了。

如果我们需要匹配至少两个连续的ss字符,需要执行如下命令:

grep "sss*" test.txt

以此类推。

注意:

正则是包含匹配,只要含有就会列出,所以单独搜索一个k,执行grep "k" test.txt 命令,也能获得和上面一样的匹配结果。如下图:

换句话说,上面这两种写法是一个意思,都是搜索含有k字母的行,一行中有一个k字母就可以,有无数个k字母也可以,都会被匹配出来。

限位(制)符:

如果是上面描述的这种简单匹配需求,使用哪种方式都可以。

但是有限位(制)符出现的匹配情况,带*的方式,处理匹配的情况更丰富。

如下面一段文本:

Stay hungry, stay foolish.  ——Steve Jobs
求知若饥,虚心若愚。——乔布斯 Stay hungry, stay folish. ——Steve Jobs
Stay hungry, stay fooolish. ——Steve Jobs
Stay hungry, stay foooolish. ——Steve Jobs
Stay hungry, stay fooooolish. ——Steve Jobs

我们可以看到上端文本中foolish中有不同数量的o。(自己随意错写的)

如果我的需求是搜索foolish单词中有三个以上数量o的行,这个时候就需要限位(制)符了,

其中foolish单词中的fl就是限位(制)符的用法。

执行命令如下:

[root@192 tmp]# grep "foooo*lish" test2.txt

结果如下:

说明:其中前三个o代表固定有三个连续的o字母出现,最后一个o*代表可以匹配0次到任意多次个o字母。

在这种需要有限位(制)符情况下的匹配,加上*就非常好处理了。

(3).练习

正则表达式.匹配除了换行符外任意一个字符。

举个例子:

文本test2.txt内容如下:

abc adapt 适应 xyz
abc adopt 采用 xyz
xyz adept 内行 abc
xyz floor 地板 abc
xyz flour 面粉 abc
  • 匹配在d和t这两个字母之间一定有两个字符的单词

    执行命令:grep "d..t" test2.txt

  • 结合*使用

    执行命令:grep "z.*a" test2.txt



    配置的是a和z两个字母之间有任何字符的内容。
  • 如果想匹配所有内容,标准写法为.*

    执行命令:grep ".*" test2.txt

(4)^$练习

正则表达式^匹配行首,$匹配行尾。

文本test2.txt内容如下:

abc adapt 适应 xyz
abc adopt 采用 xyz xyz adept 内行 abc.
xyz floor 地板 abc
xyz flour 面粉 abc
  • ^代表匹配行首,比如^a会匹配以小写a开头的行:

    执行命令:grep "^a" test2.txt

  • $代表匹配行尾,如果c$会匹配以小写c结尾的行:

    执行命令:grep "c$" test2.txt

  • ^$则会匹配空白行:

    执行命令:grep "^$" test2.txt



    在实际的应用中,我们很少这样使用,一般使用grep命令的-v选项进行取反,来过滤掉空白行。(标准方式)

    执行命令:grep -v "^$" test2.txt

  • $结合.使用

    如果我们要匹配以句号.结果的行,那是否用.$来进行匹配呢?

    我们先来执行一下命令:rep ".$" test2.txt



    我们看到是匹配了任意字符结尾的行,只是过滤的空白行。

    也就是说正则表达式.$中的.是正则符号的意思,表示匹配除了换行符外任意一个字符。

    如果我们想匹配以句号.结束的行,我们需要在.前加入转义符,把.变成普通字符串,如:\.$

    执行命令:grep "\.$" test2.txt

说明:

在使用^匹配行首,$匹配行尾的时候,如果使用的是特殊符号开头或者结尾,我们需要使用转义符进行转义,再进行匹配。

(5)[]练习

正则表达式[]匹配中括号中指定的任意一个字符,只匹配一个字符。(注意只能匹配一个字符。)

比如[abc]要么会匹配一个a字符,要么会匹配一个b字符,或者要么会匹配一个c字符。

文本test.txt内容如下:

abc adapt 适应 abc
ABC adopt 采用 xyz abc adept 内行 XYZ
123 floor 地板 ABC
123 flour 面粉 123
  • 配置adaptadoptadept这三个近似的单词。

    执行命令:grep "ad[ae]pt" test2.txt



    可以看出[].的匹配范围更精准,请根据实际情况,按需使用。
  • [0-9]会匹配任意一个数字。

    执行命令:grep "[0-9]" test2.txt

  • [A-Z]会匹配一个大写字母。

    执行命令:grep "[A-Z]" test2.txt

  • ^[a-z]代表匹配用小写字母开头的行。

    执行命令:grep "^[a-z]" test2.txt

(6)[^]练习

正则表达式[^]匹配除中括号的字符以外的任意一个字符。

就相当于在[]中的内容进行取反。

文本test.txt内容如下:

abc adapt 适应 abc
ABC adopt 采用 xyz abc adept 内行 XYZ
123 floor 地板 ABC
123 flour 面粉 123
  • 不匹配数字。

    执行命令:grep "[^0-9]" test2.txt

  • 不匹配以数字开头的行。

    执行命令:grep "^[^0-9]" test2.txt

  • 不匹配英文。

    执行命令:rep "[^a-zA-Z]" test2.txt

  • 匹配不以英文结尾的行。

    执行命令:rep "[^a-zA-Z]$" test2.txt

(7)\{n\}练习

\{n\}表示其前面的字符恰好出现n次。

提示:\{n\}中的\表示转义符,下面同理。

如下面一段文本:

Stay hungry, stay foolish.  ——Steve Jobs
求知若饥,虚心若愚。——乔布斯 Stay hungry, stay folish. ——Steve Jobs
Stay hungry, stay fooolish. ——Steve Jobs
Stay hungry, stay foooolish. ——Steve Jobs
Stay hungry, stay fooooolish. ——Steve Jobs
  • 匹配包含三个连续的o

    执行命令:grep "o\{3\}" test2.txt



    可以看到有三个连续的o,或者包含三个连续o,都会被匹配到。

    那与直接正则匹配三个o有什么区别?

    执行命令:grep "ooo" test2.txt



    原因:

    如果是想匹配一个重复的字母,直接匹配字母的方式更为方便。

    而如果我想要匹配重复任意字母或者数字,则\{n\}方式更为便捷。

    看下面练习。
  • 匹配三个连续的数字。

    文本内容如下:
    abc adapt 适应 abc
    12a adopt 采用 12345 abc adept 内行 XYZ
    1b3 floor 地板 7788999
    123 flour 面粉 123

    执行命令:grep "[0-9]\{3\}" test2.txt



    我们可以看到,有三个连续的数字,或者包含有三个连续数字的文本,都被匹配到了。

    如果我们要是不用\{n\}的方式进行正则匹配的话,如下:

    执行命令:grep "[0-9][0-9][0-9]" test2.txt



    我们可以看到上边的命令就会麻烦很多,如果要是匹配10个连续的数字,那命令就非常的冗余了。

    字母也是同理的。

  • 只匹配三个连续的数字

    虽然上面的12345和7788999是包含三个连续的数字,所以也是可以列出的。

    可是这样不能体现出来[0-9]\{3\}只能匹配三个连续的数字,而不是匹配四个连续的数字。

    那么正则中就应该加入限位(制)符(可以是前后有标识的字符或者是行尾行首等进行限位),如下:

    执行命令,限制行首:grep "^[0-9]\{3\}" test2.txt



    或者限制行尾,注意前边要多加一个空格限位,才能符合该需求。

    执行命令:grep " [0-9]\{3\}$" test2.txt

  • 用上面一段文本,练习匹配只包含三个o的文本。

    执行命令:grep "fo\{3\}l" test2.txt



    说明:fl就是限位(制)符。

注意:

\{n\}匹配的方式一般不会用于匹配字母,多用于匹配数字,如电话号码。

还要再重复一遍,正则表达式是包含匹配,多注意限位(制)符的使用。

(8)\{n,\}练习

\{n,\}表示其前面的字符出现不小于n次。

如下面一段文本:

Stay hungry, stay foolish.  ——Steve Jobs
求知若饥,虚心若愚。——乔布斯 Stay hungry, stay folish. ——Steve Jobs
Stay hungry, stay fooolish. ——Steve Jobs
Stay hungry, stay foooolish. ——Steve Jobs
Stay hungry, stay fooooolish. ——Steve Jobs

比如fo\{4,\}l这个正则就会匹配用f开头,l结尾,中间最少有4个o的字符串。

执行命令:grep "fo\{4,\}l" test2.txt

正则表达是fo\{4,\}looooo*的区别同上边(7)\{n\}同理。

练习:匹配至少连续5个字数的文本。

abc adapt 适应 abc
12a adopt 采用 12345 abc adept 内行 XYZ
1b3 floor 地板 7788999
123 flour 面粉 123

执行命令:grep "[0-9]\{4,\}" test2.txt

(9)\{n,m\}练习

\{n,m\}匹配其前面的字符至少出现n次,最多出现m次。

下面一段文本:

Stay hungry, stay foolish.  ——Steve Jobs
求知若饥,虚心若愚。——乔布斯 Stay hungry, stay folish. ——Steve Jobs
Stay hungry, stay fooolish. ——Steve Jobs
Stay hungry, stay foooolish. ——Steve Jobs
Stay hungry, stay fooooolish. ——Steve Jobs
Stay hungry, stay foooooolish. ——Steve Jobs

匹配在字母f和字母l之间有最少3个o,最多5个o

执行命令:grep "fo\{3,5\}l" test2.txt

4、总结

我们学习Shell的正则表达式,实际的应用是什么?

  • 主要是做字符串的模糊匹配,比如要求你输入一个手机号,或者身份证号,再或者是一个邮箱地址等,做模糊匹配,进行错略的过滤,来过滤掉一些不符合规则的输入。(更细的验证在后台处理,如短信或者邮箱等验证操作)
  • 还有再Shell中我们也常常会读取文本中的数据,这些文本中的数据也是字符串,我们通过正则表达式来过滤出一些我们需要的数据信息。

提示:要注意区分正则表达式和通配符中的符号功能的不同。

『忘了再学』Shell基础 — 24、Shell正则表达式的使用的更多相关文章

  1. 『忘了再学』Shell基础 — 10、Bash中的特殊符号(二)

    提示:本篇文章接上一篇文章,主要说说()小括号和{}大括号的区别与使用. 8.()小括号 ():用于一串命令执行时,()中的命令会在子Shell中运行.(和下面大括号一起说明) 9.{}大括号 {}: ...

  2. 『忘了再学』Shell基础 — 20、Shell中的运算符

    目录 1.Shell常用运算符 2.Shell中数值运算的方法 (1)方式一 (2)方式二 (3)方式三(推荐) 1.Shell常用运算符 Shell中常用运算符如下表: 优先级数值越大优先级越高,具 ...

  3. 『忘了再学』Shell基础 — 2、Shell的作用与分类

    目录 1.Shell的作用 2.Shell的分类 1.Shell的作用 Shell除了能解释用户输入的命令,将它传递给内核,还可以: 调用其他程序,给其他程序传递数据或参数,并获取程序的处理结果. 在 ...

  4. 『忘了再学』Shell基础 — 12、用户自定义变量

    目录 1.变量定义 2.变量调用 3.变量的修改 4.查看变量 (1)-u选项说明: (2)-x选项说明: (3)set命令说明: 5.变量删除 1.变量定义 变量正确定义. 格式:变量名=" ...

  5. 『忘了再学』Shell基础 — 3、echo命令的介绍与使用

    目录 1.echo命令的作用 2.echo命令的基本用法 3.echo命令的-e选项用法 4.echo命令一些特殊用法 (1)输出字符带有字体颜色 (2)输出字符带有背景颜色 在讲Shell脚本之前, ...

  6. 『忘了再学』Shell基础 — 25、扩展正则表达式

    目录 1.扩展正则表达式说明 2.练习 (1)+和?练习 (2)|和()练习 3.注意(重点) 1.扩展正则表达式说明 熟悉正则表达式的童鞋应该很疑惑,在其他的语言中是没有扩展正则表达式说法的,在Sh ...

  7. 『忘了再学』Shell基础 — 30、sed命令的使用

    目录 1.sed命令说明 2.行数据操作 (1)查看文件中的数据 (2)删除文件中的数据 (3)向文件中追加数据 (4)向文件中插入数据 (5)修改文件中的多行数据(删除,追加,插入) (6)替换文件 ...

  8. 『忘了再学』Shell基础 — 1、Shell的介绍

    目录 1.Shell的由来 2.Shell的两种执行指令方式 3.什么是Shell脚本 4.Shell 是一种脚本语言 1.Shell的由来 我们比较熟悉Windows系统的图形化界面,对于图形界面来 ...

  9. 『忘了再学』Shell基础 — 4、Bash基本功能(history命令)

    目录 1.history历史命令 2.设置命令历史记录的条数 3.清空历史命令 4.历史命令的调用 5.命令与文件的补全 在Linux系统中默认的Shell就是Bourne-AgainShell(简称 ...

随机推荐

  1. sequelize模型

    model表示数据库中的表,有时它也会被称为"模型"或"工厂".Model不能通过构造函数创建,只能通过sequlize.define方法来定义或通过sequl ...

  2. I/O 引脚

    我们以网卡举例 引脚,芯片,pcb板之间的关系非常紧密 1.引脚,又叫管脚,英文叫Pin. 就是从集成电路(芯片)内部电路引出与外围电路的接线,所有的引脚就构成了这块芯片的接口.引线末端的一段,通过软 ...

  3. 服务器的cpu 核心、线程

    此版本有大范围改动,因为cpu作为一个大脑,所以更细致的进行了,相关的分析和阐述. 1.版本1. 2022.1.242.版本2: 2022.3.2 采集数据: ht2机器为物理机,cpu是4颗cpu, ...

  4. Blazor 发布WebAssembly使用Brotli 压缩提升初次加载速度

    使用Brotli提高网站访问速度 在优化网站打开速度上,我们有很多的方法,而其中一个就是减少诸如Javascript和CSS等资源文件的大小,而减少文件大小的方法除了在代码上下功夫外,最常用的方法就是 ...

  5. springcloud集群测试

    使用ribbon实现负载均衡,访问同一个url,轮询不同的服务提供端,从不同的数据库中取数据.

  6. 删库到跑路?还得看这篇Redis数据库持久化与企业容灾备份恢复实战指南

    本章目录 0x00 数据持久化 1.RDB 方式 2.AOF 方式 如何抉择 RDB OR AOF? 0x01 备份容灾 一.备份 1.手动备份redis数据库 2.迁移Redis指定db-数据库 3 ...

  7. Java语言学习day17--7月23日

    1.面向对象思想2.类与对象的关系3.局部变量和成员变量的关系4.封装思想5.private,this关键字6.随机点名器 ###01面向对象和面向过程的思想 * A: 面向过程与面向对象都是我们编程 ...

  8. 「Python实用秘技07」pandas中鲜为人知的隐藏排序技巧

    本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第7期 ...

  9. 论文解读(IGSD)《Iterative Graph Self-Distillation》

    论文信息 论文标题:Iterative Graph Self-Distillation论文作者:Hanlin Zhang, Shuai Lin, Weiyang Liu, Pan Zhou, Jian ...

  10. AcWing-3167. 星星还是树 -c++题解(模拟退火)

    ​ 在二维平面上有 n 个点,第 i 个点的坐标为 (xi,yi).请你找出一个点,使得该点到这 n个点的距离之和最小.该点可以选择在平面中的任意位置,甚至与这 n个点的位置重合. 输入格式 第一行包 ...