04 Shell编程之正则表达式与文本处理器

1、正则表达式

1.1 正则表达式的定义

正则表达式又称为正规表达式、常规表达式。

正则表达式是使用单个字符来描述、匹配一系列符合某个句法规则的字符串,

简单来说,正则表达式就是一种匹配字符串的方法(通过一些特殊符号,实现快速查找、删除、替换某个特定字符串)

注:正则表达式(在代码中常简写为regex、regexp或RE)是由普通字符与元字符组成的文字模式。

普通字符包括大小写字母、数字、标点符号及一些其他符号;

元字符是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符在目标对象中的出现模式。

正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

正则表达式一般用于脚本编程与文本编辑器中。正则表达式具备很强大的文本匹配功能,能够在

文本海洋中快速高效地处理文本。

1.2 正则表达式的用途

由于系统在运行中会产生大量的信息,而这些信息有些是非常重要的,有些仅仅是告知信息。

身为系统管理员如果直接看到这么多的信息数据,就无法快速准确定位到重要的信息。

这时候就可以通过正则表达式快速提取“有问题”的信息。这样就可以使运维工作变得更加简单,方便。

例如,在Internet中,垃圾/广告邮件经常会造成网络塞车,而如果在服务器端就将这些问题邮件提前踢除的话,客户端就会减少很多不必要的带宽消耗。

而目前常用的邮件服务器postfix以及支持邮件服务器的相关分析软件都支持正则表达式的对比功能

(将来信的标题、内容与特殊字符串进行对比,发现问题邮件就过滤掉)

1.3 基础正则表达式

根据不同的严谨程度与功能可将正则表达式分为基本正则表达式、扩展正则表达式。

在Linux系统中,常见的文本处理工具grep与sed支持基本正则表达式;

而egrep与awk支持扩展正则表达式。

1.3.1 基础正则表达式的实验实例

首先需要先准备一个名为test.txt的测试文件,如下图:

完成test.txt文件的填写之后,保存并退出vim编辑器。

(1)查找特定字符

注:-n——表示显示行号;

-i——表示不区分大小写;

执行如下图中的命令,可以在test.txt文件中查找出特定字符the所在的位置(命令执行后,符合匹配条件的字符,字体颜色会变为红色):

若反向选择,可使用grep命令的-v选项来实现。如下图:

补充:grep命令的-v选项,表示反转匹配或排除匹配。即-v选项会输出不匹配指定模式的行,而不是匹配的行。

如果用户想要查找不包含某个特定字符串的行,就可以使用grep -v命令来实现。

(2)利用中括号[]来查找集合字符

中括号[]里无论有几个字符,都仅代表一个字符,也就是说[io]表示匹配i或者o。

例如,执行以下命令就可以同时查找到shirt与short这两个字符串。

若要查找包含重复单个字符oo时,可执行下图中的命令:

补充:若要查找oo前面不是w的字符串,只需要通过集合字符的反向选择[^]来实现该目的。

例如,执行下图中的命令可找到oo前面不是w的字符串:

注:上图中,通过执行后的结果可以查看到,第十二行、第十三行中的#woood#和

#wooooood#,二者前面也包含w,那这是怎么回事呢?不是要把所有oo前面是w的字符行都给过滤掉了吗?

其实,从上图的执行结果中就可以看出来,第十二行的#woood#中加粗显示的是ooo而不是oo。也就是说,oo前面的那个o也是符合规则的,是不能被过滤掉的;

同理,第十三行的#wooooood#中,加粗显示的是oooooo而不是oo。也就是说oo前面的oooo也是符合规则的,是不能被过滤掉的。

若不希望oo前面存在小写字母,可以使用下图中的命令来实现:

注:a-z表示小写字母;A-Z表示大写字母

若希望查找文本中包含数字的行,可以通过下图中的命令来实现:

(3)查找行首“^”与行尾字符“$”

基础正则表达式包含两个定位元字符:^表示行首的意思;$表示行尾的意思

例如,在上面的查询the字符串时出现了很多包含the的行,

如果想要查询以the字符串为行首的行,就可以通过元字符^来实现,如下图:

若要查询以小写字母开头的行,可以使用^[a-z]来过滤,如下图:

若要查询以大写字母开头的行,则可以使用^[A-Z]来过滤,如下图:

若查询不以字母开头的行,则可以使用^[^a-zA-Z]规则来过滤,如下图:

补充:^符号在元字符[]符号内外的作用是不一样的,

在[]符号内——表示反向选择;

在[]符号外——代表定位行首。

若想查找以某一特定字符结尾的行,则可以使用$定位符。

例如,执行下图中的命令,可以查找到以小数点.结尾的行。

补充:因为小数点.在正则表达式里面也是一个元字符,所以需要在这里用转义字符\

将具有特殊意义的字符转化为普通字符。

如果要查询空白行,可执行下图中的命令:

(4)查找任意一个字符.与重复字符*

小数点.在正则表达式中也是一个元字符,代表任意一个字符。

例如,执行下图中的命令就可以查找以w开头以d结尾的字符串,共有四个字符。

*代表的是重复前面的单字符零个或多个。

例如,o*——表示拥有0个或大于等于1个o的字符

(因为允许空字符,所以执行下图中的命令时,会将文本中所有的内容都输出打印)

若是oo*,则第1个o必须存在,第2个o可以是0个或多个。如下图所示:

同理,若是查询包含至少两个o以上的字符串,则执行下面的命令即可:

若想查询以w开头以d结尾,中间至少包含一个o的字符串,可执行下图中的命令:

若想查询以w开头以d结尾,中间字符可有可无的字符串,可执行下图中的命令:

若想查询任意数字所在的行,可执行下图中的命令:

(5)查找连续字符范围{}

如果想要限制一个范围内的重复字符串该如何实现呢?

比如说,要查找三到五个o的连续字符,这时候就需要使用基础正则表达式中限定范围的字符{}了。

注:{}在Shell中具有特殊意义,所以在使用{}字符时,需要利用转义字符\将{}字符转换成普通字符。

下面介绍一下{}字符的使用方法:

查询两个o的字符:

查询以w开头以d结尾,且中间包含2~5个o的字符串:

查询以w开头以d结尾,中间包含2个或2个以上o的字符串:

2、元字符总结

基础正则表达式的元字符主要包括有:

3、扩展正则表达式

grep命令仅支持基础正则表达式,如果要只要扩展正则表达式,需要使用egrep或awk命令。

注:egrep命令是一个搜索文件获得模式,

使用该命令可以搜索文件中的任意字符串和符号,

也可以搜索一个或多个文件的字符串,

egrep命令与grep命令的用法基本相似。

与基本正则表达式类似,扩展正则表达式也包含多个元字符,常见的扩展正则表达式的元字符主要有:

4、文本处理器

grep、sed、awk是Shell编程中经常用到的文本处理工具,被称为Shell编程三剑客。

4.1 sed工具

sed工具是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或仅输出处理的某些行。

注:sed也可以在无交互的情况下实现相当复杂的文本处理操作。

sed的工作流程主要包括读取、执行和显示三个过程:

  • 读取:sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间)
  • 执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行。
  • 显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。

注:默认情况下,所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。

4.2 sed命令的常见用法

通常情况下,sed命令有两种格式,如下图所示:

注:操作用于对文件操作的动作行为,也就是sed的命令。

常见的sed命令选项主要有:

-e——表示指定命令或者脚本来处理输入的文本文件

-f——表示用指定的脚本文件来处理输入的文本文件

-h——显示帮助

-n——表示仅显示处理后的结果

-i——直接编辑文本文件

常见的操作有:

a——增加,在当前行下面增加一行内容

c——替换,将选定行替换为指定内容

d——删除,删除选定的行

i——插入,在选定的行上面插入一行指定内容

p——打印,

注:如果同时指定行,表示打印指定行;

如果不指定行,则表示打印所有内容;

如果有非打印字符,则以ASCII码输出,其通常与-n选项一起使用

s——替换,替换指定字符

y——字符转换

4.3 sed用法实例

以上面创建的test.txt文件为例,进行演示。

(1)输出符合条件的文本(p——表示正常输出)

若只想输出test.txt文件中的第3行内容,可以执行下列命令:

若向输出test.txt的第3~5行内容,可执行下图中的命令:

若向输出所有的奇数行,可用下图中的命令:

若想输出所有的偶数行,可以执行下图中的命令:

若想输出第1~5行之间的奇数行(第1、3、5行),可以执行下图中的命令:

若想输出第10行至文件结尾之间的偶数行,可执行下图中的命令:

注:在上图中,如果单引号换成双引号使用的话,这时候如果会报错,就要在$前面加上一个转移符才可以。如下图:

(2)sed命令结合正则表达式使用

sed命令结合正则表达式时,格式略有不同。正则表达式以/包围。

例如,若要输出test.txt文件中,包含the的行,可以使用下图中的命令。其中,the要被/包围:

若要输出第4行至第一个包含the的行,可以执行下图中的命令:

若想输出包含the的行所在的行号,可执行下图中的命令:

若想输出test.txt文件中以PI开头的行,可执行下图中的命令:

若想输出以数字结尾的行,可以执行下图中的命令:

若想输出包含单词wood的行,可执行下图中的命令:

注:\< 、\>代表单词的边界

(3)删除符合条件的文本(d)

nl命令用于计算文件的行数,结合该命令可以更加直观地查看到命令执行的结果。如下图:

若想删除test.txt文件中的第3行,可以执行下图中的命令:

若想删除第3~5行,可以执行下图中的命令:

若想删除包含cross的行,可以执行下图中的命令:

注:如果要删除不包含cross的行,用!表示取反操作。如下图:

若要删除以小写字母开头的行,可以执行下图中的命令:

若要删除以.结尾的行,可执行如下图的命令:

若要删除所有的空行,可以执行下图中的命令:

(4)替换符合条件的文本

在使用sed命令进行替换操作时,需要用到s(字符串替换)、c(整行/整块替换)、y(字符转换)这些命令选项。

若想将每行中的第一个the替换为THE,可以执行下图中的命令:

若想将每行中的第2个l替换为L,可以执行下图中的命令:

将文件中的所有the替换为THE,可以执行下图中的命令:

若想将文件中的所有o删除(即替换为空的字符串),可以执行下图中的命令:

若想在每行的行首都插入#号,可以执行下图中的命令:

当然也可以通过加g,来实现全局都以#开头的效果,如下图:

若想在包含the的每行行首都插入#号,可以执行下图中的命令:

若想在每行的行尾都插入字符串EOF,可以执行下图中的命令:

若想将第3~5行中的所有the替换为THE,可以执行下图中的命令:

若要将包含the的所有行中的o都替换为O,可执行下图中的命令:

(5)迁移符合条件的文本

使用sed命令迁移符合条件的文本时,常用到以下参数:

H——复制到剪切板;

g、G——将剪切板中的数据覆盖/追加至指定行;

w——保存为文件

r——读取指定文件

a——追加指定内容

若想将包含the的行迁移至文件末尾,可执行下图中的操作:

若想将第1~5行的内容转移至第17行之后,可执行下图中的命令:

若想将包含the的行,另存为文件out.file,可执行下图中的命令:

  • 34
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值