目录
前言
本章节将深入探讨正则表达式的定义、用途及其基础与扩展用法。通过具体的示例,你将学会如何利用正则表达式快速查找、删除、替换文本中的特定字符串,从而提升文本处理的效率与准确性。
文本处理器在She11编程中同样占据着举足轻重的地位。grep、sed、awk作为Shell编程中的“三剑客”,各自拥有独特的优势与广泛的应用场景。
grep、sed、awk作为Shell编程中的“三剑客”,各自拥有独特的优势与广泛的应用场景。本章将详细介绍这些工具的使用方法,包括基本的文本搜索、复杂的文本替换、格式化的文本输出等。
一:正则表达式
1.正则表达式的定义
正则表达式又称正规表达式、常规表达式。在代码中常简写为regex、regexp或RE。正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,简单来说,是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。
2.正则表达式用途
对于一般计算机用户来说,由于使用到正则表达式的机会不多,所以无法体会正则表达式的魅力,而对于系统管理员来说,正则表达式则是必备技能之一。
正则表达式对于系统管理员来说是非常重要的,系统运行过程中会产生大量的信息,这些信息有些是非常重要的,有些则仅是告知的信息。身为系统管理员如果直接看这么多的信息数据,无法快速定位到重要的信息,如“用户账号登录失败”“服务启动失败”等信息。这时可以通过正则表达式快速提取“有问题”的信息。如此一来,可以将运维工作变得更加简单、方便。
二:基础正则表达式
1.基础正则表达式示例
提前准备一个名为test.txt 的测试文件,文件内容如下所示。
(1)查找特定字符
如执行以下命令即可从test.txt文件中查找出特定字符“the”所在位置其中“-n”表示显示行号、“-i”表示不区分大小写。命令执行后,符合匹配标准的字符。(本章中全部通过加粗显示代替)。
若反向选择,如查找不包含“the"字符的行,只需要通过grep命令的”-v“选项,并配合”-n“一起使用行号。
(2)利用”[ ]“ 来查找集合字符
想要查找“shirt”与“short”这两个字符串时,可以发现这两个字符串均包含“sh”与“rt”。
此时执行以下命令即可同时查找到“shirt”与“short”这两个字符串,其中“[ ]”中无论有几个字符,都仅代表一个字符,也就是说“[io]”表示匹配“i”或者“o”。
若要查找包含重复单个字符”oo"时:只需执行以下命令:
若要查找“oo“前面不是”w"的字符串,需要通过集合字符的反向选择“[^]”来实现该目的。
例如:在文本中查找“oo”前面不是“w”的字符串。
若不希望“oo”前面存在小写字母可以通过[^a-z]来表示具体命令如下:
查找包含数字的行:
(3)查找行首“^”与行尾"$"
基础正则表达式包含两个定位元字符:“^(行首)与“$”(行尾)。在上面的示例中,查询“the”字符串时出现了很多包含“the”的行,如果想要查询以“the”字符串为行首的行,则可以通过“^”元字符来实现。
查询以小写字母开头的行可以通过“^[a-z]”规则来过滤:
查询大写字母开头的行则使用“^[A-Z]”规则:
若查询不以字母开头的行则使用“^[^a-zA-Z]”规则:
“^”符号在元字符集合“[ ]”符号内外的作用是不一样的,在“[]”符号内表示反向选择,在“[ ]”符号外则代表定位行首。反之,若想查找以某一特定字符结尾的行则可以使用“$”定位符。
例如:执行以下命令即可实现查询以小数点(.)结尾的行。因为小数点(,)在正则表达式中也是一个元字符,所以在这里需要用转义字符“\”将具有特殊意义的字符转化成普通字符。
(4)查找任意字符“."与重复字符“*”
在正则表达式中“."也是一个元字符,代表任意一个字符
例如:执行以下命令可以查找”w??d“的字符,以w开头 d结尾
执行以下命令即可查询以w开头d结尾,中间的字符可有可无的字符串。
执行以下命令即可查询任意数字所在的行。
(5)查找连续字符范围”{ }“
如果想要限制一个范围内的重复的字符串该如何实现呢?
例如,查找三到五个o的连续字符,这个时候就需要使用基础正则表达式中的限定范围的字符“(}”。因为“()”在Shell中具有特殊意义,所以在使用“{}”字符时,需要利用转义字符“”,将“{}”字符转换成普通字符。“{}”字符的使用方法如下所示。
查询两个o的字符
查询以w开头以d结尾,中间包含2~5个o的字符串
查询以w开头以d结尾,中间包含2个或2个以上o的字符串
2.元字符总结
字符 | 说明 |
\ | 将下一个字符标记为一个特殊字符,或一个原义字符,或向后 引用,或一个八进制转义符 |
^ | 匹配输入字符开始的位置 |
$ | 匹配输入字符的结束为止 |
* | 匹配前面的子表达式0次或者多次 |
+ | 匹配前面的子表达式一次或多次 |
? | 匹配前面的子表达式0次或者一次 |
. | 匹配除换行字符(\n \r)之外的任何字符 |
[a-z] | 字符范围,匹配指定范围内的任意字符 |
{n} | n是一个非负整数,匹配确定的n次 |
{n,} | n是一个非负整数,至少匹配n次 |
{n,m} | n,m均为非负整数,其中n<=m,最少匹配n次,最多匹配m次 |
\d | 匹配一个数字字符,等价于[0-9] |
\D | 匹配一个非数字字符,等价于[^0-9] |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于[^\f\n\r\t\v]。 |
\w | 匹配字母、数字、下划线。等价于"[A-Za-z0-9_]'。 |
\W | 匹配非字母、数字、下划线。等价于'[^A-Za-z0-9_]'。 |
\n | 匹配一个换行符 |
\f | 匹配-一个换页符 |
\r | 匹配一个回车符 |
3.扩展正则表达式
通常情况下会使用基础正则表达式就已经足够了,但有时为了简化整个指令,需要使用范围更广的扩展正则表达式。
例如,使用基础正则表达式查询除文件中空白行与行首为“#”之外的行(通常用于查看生效的配置文件),执行“grep-v'^$’test.txtlgrep-V'^#’”即可实现。这里需要使用管道命令来搜索两次。如果使用扩展正则表达式,可以简化为“egrep-V'^$|^#’test.txt”,其中,单引号内的管道符号表示或者(or)。
与基础正则表达式类型相同,扩展正则表达式也包含多个元字符,常见的扩展正则表达式的元字符主要包括以下几个,如下表所示。
元字符 | 作用与示例 |
+ | 作用:重复一个或一个以上的前一个字符 示例:执行“egrep -n'wo+d' test.txt”命令,即可査询"wood""woood"“woo00oood"等字符串 |
? | 作用:零个或者一个的前一个字符 示例:执行“egrep -n'bes?t' test.txt"命令,即可査询"bet""best"这两个字符串 |
| | 作用:使用或者(or)的方式找出多个字符 示例:执行“egrep -n'ofis|on'test.txt”命令即可査询"of"或者"if或者"on"字符串 |
() | 作用:查找“组"字符串 示例:"egrep -n"(ale)st test.txt"。"tast"与"test因为这两个单词的“t"与"st"是重复的,所以将“a"与"e列于“0"符号当中,并以“"分隔,即可查询"tast"或者"test"字符串 |
()+ | 作用:辨别多个重复的组 示例:“egrep -n'A(xyZ)+C'test.tx!"。该命令是査询开头的"A"结尾是"C",中间有一个以上的"xyZ"字符串的意思 |
二:文本处理器
1.sed工具
sed(stream EDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出处理的某些行。sed也可以在无交互的情况下实现相当复杂的文本处理操作,被广泛应用于She11脚本中,用以完成各种自动化处理任务。
sed 的工作流程主要包括读取、执行和显示三个过程。
- 读取:sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。
- 执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则 sed命令将会在所有的行上依次执行。
- 显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。
sed [ 选项 ] ' 操作 ' 参数
sed [ 选项 ] -f scriptfile 参数
常见的sed命令选项主要包含以下几种。
- -e 或 --expression=:表示用指定命令或者脚本来处理输入的文件。
- -f 或 -file=: 表示用指定的脚本文件来处理输入的文本文件。
- -h 或 --help: 显示帮助。
- n、--quiet 或 silent: 表示仅显示处理后的结果。
- -i:直接编辑文本文件。
“操作”用于指定对文件操作的动作行为,也就是sed的命令。通常情况下是采用的“[n1[,n2]]”操作参数的格式。n1、n2是可选的,代表选择进行操作的行数,如操作需要在5~20行之间进行,则表示为“5,20 动作行为”。常见的操作包括以下几种。
- a: 增加,在当前行下面增加一行指定内容。
- C: 替换,将选定行替换为指定内容。
- d: 删除,删除选定的行。
- i: 插入,在选定行上面插入一行指定内容。
- P: 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出。其通常与“-n”选项一起使用。
- s:替换,替换指定字符。
- y: 转符转换
(1)输出符合条件的文本(p表示正常输出)
输出第3行:
输出3~5行:
输出所有奇数行,n表示读入下一行资料:
输出所有偶数行:
输出包含the的行号,=用来输出行号
输出以数字结尾的行
输出包含word的行,\<,\>代表单词边界
(2)删除符合条件的文本
因为后面的示例还需要使用测试文件test.txt,所以在执行删除操作之前需要先将测试文件备份以下示例分别演示了 sed 命令的几种常用删除用法。
删除第3行
下面命令中n1命令用于计算文件的行数,结合该命令可以更加直观地查看到命令执行的结果。
删除3~5行
//删除包含cross的行,原本的第8行被删除:
删除以“."结尾的行
删除所有空行
(3)替换符合条件的文本
在使用sed命令进行替换操作时需要用到s(字符串替换)、c(整行/整块替换)、y(字符转换)命令选项,常见的用法如下所示。
将每行中的第一个the替换为THE
将每行中的第2个1替换为L
将文件中的所有the替换为THE
将文件中的所有·删除(替换为空串)
在每行行首插入#号
将第3~5行中的所有the替换为THE
将包含the的所有行中的o都替换为O
(4)迁移符合条件的文本
使用sed命令迁移文本时,常用到以下参数:
- H:复制到剪贴板
- g、G:将剪贴板中的数据覆盖/追加至指定行
- w:保存为文件
- r:读取指定文件
- a:追加指定内容
将包含the的行迁移至文件末尾,{;}用于多个操作
将第1~5行内容转移至第17行后
将包含the的行存为文件out.file
在第3行后插入一个新行,内容为New
在第3行后插入多行内容,中间的\n 表示换行
(5)使用脚本编辑文件
使用sed脚本将多个编辑指令存放到文件中(每行一条编辑指令),通过“-f”选项来调用。例如执行以下命令即可将第1~5行内容转移至第17行后。
以上操作可以改用脚本文件方式:
2.awk工具
通常情况下awk所使用的命令格式如下所示,其中,单引号加上大括号“{}”用于设置对数据进行的处理动作。awk可以直接处理目标文件,也可以通过“-f”读取脚本对目标文件进行处理
在Linux系统中/etc/passwd是一个非常典型的格式化文件,各字段间使用“:”作为分隔符隔开Linux系统中的大部分日志文件也是格式化文件,从这些文件中提取相关信息是运维的日常工作内容之若需要查找出/etc/passwd的用户名、用户ID、组ID等列,执行以下awk 命令即可。
awk包含几个特殊的内建变量:
- FS:指定每行文本的字段分隔符,默认为空格或制表位。
- NF:当前处理的行的字段个数。
- NR:当前处理的行的行号(序数)。
- $8:当前处理的行的整行内容。
- $:当前处理行的第n个字段(第n列)。
- FILENAME:被处理的文件名。
- 数据记录分隔,默认为\n,即每行为一条记录:
用法示例:
(1)按行输出文本
输出所有内容
输出第1~3行内容
输出第1行、第3行内容
输出所有奇数行的内容
输出以root 开头的行
输出以 nologin 结尾的行
(2)按字段输出文本
输出每行中(以空格或制表位分隔)的第3个字段
输出密码为空的用户的shadow记录
(3)通过管道,双引号调用Shell命令
调用w-1命令统计使用bash的用户个数,等同于grep-c"bash$”/etc/passwd
调用W命令,并用来统计在线用户数
调用hostname,并输出当前的主机名