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,可执行下图中的命令: