shell 正则表达式与文本处理器

目录

前言

一、正则表达式

(一)定义与用途

(二)基础正则表达式

(三)基础正则表达式元字符

(四)扩展正则表达式

二、文本处理器:Shell 编程的得力助手

(一)sed 工具

(二)awk 工具


前言

在 Shell 编程领域,正则表达式与文本处理器是极为关键的技术,对于系统管理员、开发人员以及数据分析师而言,熟练掌握这些技能,能够显著提升文本处理的效率和准确性,为编写高效、灵活的 Shell 脚本奠定坚实基础。

一、正则表达式

(一)定义与用途

正则表达式(Regular Expression,简称 RE),又被称作正规表达式、常规表达式,在代码中常简写为 regex、regexp。它是一种利用单个字符串来描述、匹配一系列符合特定句法规则字符串的强大工具 。在 Shell 编程中,正则表达式主要用于文本的查找、替换、删除等操作,广泛应用于文本编辑器、程序设计语言以及各类数据处理场景。

(二)基础正则表达式

为深入理解基础正则表达式,我们准备一个名为 test.txt 的测试文件,内容如下:

he was short and fat. He was wearing a blue polo shirt with black pants.The home
of Football on BBC Sport online.
the tongue is boneless but it breaks bones.12!
google is the best tools for search keyword. The year ahead will test our political
establishment to the limit. P1=3.141592653589793238462643383249901429
a wood cross!
Actions speak louder than words
#woood #
#woooooood #
Axy zxyzxyzxyzC
I bet this place is really spooky late at night!
Misfortunes never come alone/single.
I shouldn't have lett so tast.

  1. 查找特定字符:使用 grep 命令结合正则表达式可实现特定字符的查找。

例如,执行 “grep -n 'the' test.txt”,“-n” 选项用于显示行号,该命令会在 test.txt 文件中查找包含 “the” 的行,并输出行号及匹配行内容 。若加上 “-i” 选项,即 “grep -in 'the' test.txt”,则表示不区分大小写进行查找。若要反向选择,查找不包含 “the” 字符的行,可使用 “grep -vn 'the' test.txt”,“-v” 选项表示反向匹配。

  1. 利用中括号查找集合字符:中括号 “[]” 在正则表达式中用于匹配集合内的任意一个字符。

比如,查找 “shirt” 与 “short” 这两个字符串,可执行 “grep -n'sh [io] rt' test.txt” ,因为 “[io]” 表示匹配 “i” 或者 “o”。查找包含重复单个字符 “oo” 的行,执行 “grep -n 'oo' test.txt”。若要查找 “oo” 前面不是 “w” 的字符串,可使用集合字符的反向选择 “[^]”,即 “grep -n '[^w] oo' test.txt”。查找包含数字的行,执行 “grep -n '[0-9]' test.txt”。

  1. ** 查找行首 “^” 与行尾字符 “:表示行首,” 表示行尾。
“grep -n '^the' test.txt”             #查询以 “the” 字符串为行首的行        
“grep -n '^[a-z]' test.txt”           #查询以小写字母开头的行
“grep -n '^[A-Z]' test.txt”           #查询大写字母开头的行
“grep -n '[a-zA-Z]' test.txt”         #查询不以字母开头的行
“grep -n '^$' test.txt”								#查询空白行

查找以小数点 “.” 结尾的行时,由于小数点在正则表达式中是元字符,需使用转义字符 “\”,即 “grep -n '.' test.txt”。

  1. 查找任意一个字符 “.” 与重复字符 “*”:在正则表达式中,小数点 “.” 代表任意一个字符(除换行符外)。

例如,执行 “grep -n 'w..d' test.txt”,可查找以 “w” 开头、“d” 结尾且中间有两个任意字符的字符串。“” 代表重复零个或多个前面的单字符。如 “grep -n 'oo' test.txt”,“oo*” 表示第一个 “o” 必须存在,第二个 “o” 则是零个或多个 “o”。若查询包含至少两个 “o” 以上的字符串,执行 “grep -n 'ooo*' test.txt”。查询以 “w” 开头 “d” 结尾,中间包含至少一个 “o” 的字符串,执行 “grep -n 'woo*d' test.txt”;查询以 “w” 开头 “d” 结尾,中间的字符可有可无的字符串,执行 “grep -n 'w.d' test.txt”查询任意数字所在行,执行 “grep -n '[0-9][0-9]' test.txt”。

  1. 查找连续字符范围 “{}”:“{}” 用于限制重复字符的范围,在 Shell 中使用时需用转义字符 “\”。

例如:

“grep -n 'o {2}' test.txt”         #查询两个 “o” 的字符
“grep -n 'wo {2,5} d' test.txt”    #查询以 “w” 开头以 “d” 结尾,中间包含 2 - 5 个 “o” 的字符串
“grep -n 'wo {2,} d' test.txt”     #查询以 “w” 开头以 “d” 结尾,中间包含 2 个或 2 个以上 “o” 的字符串

(三)基础正则表达式元字符

常见的基础正则表达式元字符如下表所示:

字符

说明

|

将 | 前命令的输出作为 | 后命令的输入

^

匹配输入字符串的开始位置

$

匹配输入字符串的结束位置

*

匹配前面的子表达式零次或多次

+

匹配前面的子表达式一次或多次

?

匹配前面的子表达式零次或一次

.

匹配除换行符(\n、\r)之外的任何单个字符

[a - z]

字符范围。匹配指定范围内的任意字符

{n}

n 是一个非负整数,匹配确定的 n 次

{n,}

n 是一个非负整数,至少匹配 n 次

{n,m}

m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次

\d

匹配一个数字字符。等价于 [0 - 9]

\D

匹配一个非数字字符。等价于 [^0 - 9]

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\n\t\v]

\S

匹配任何非空白字符。等价于 [^\n\t\v]

\w

匹配字母、数字、下划线。等价于 '[A - Za - z0 - 9_]'

\W

匹配非字母、数字、下划线,等价于 '[^A - Za - z0 - 9_]'

\n

匹配一个换行符

\r

匹配一个换页符

\v

匹配一个回车符

(四)扩展正则表达式

在某些场景下,为简化指令,可使用扩展正则表达式。例如,查看生效的配置文件(排除空白行与行首为 “#” 的行),使用基础正则表达式需执行 “grep -v '^' test.txt|grep -v '^\#'”,而使用扩展正则表达式,可简化为“egrep -v '^|^#' test.txt”,其中单引号内的管道符号 “|” 表示 “或者(or)” 。grep 命令仅支持基础正则表达式,若使用扩展正则表达式,需使用 egrep 或 awk 命令。egrep 命令与 grep 命令用法基本相似,可用于搜索文件中的任意字符串和符号。
扩展正则表达式常见元字符如下:

元字符

作用与示例

+

重复一个或者一个以上的前一个字符。

?

零个或者一个的前一个字符。

**

使用或者(or)的方式找出多个字符。

()

查找 “组” 字符串。

()+

辨别多个重复的组。

二、文本处理器:Shell 编程的得力助手

在 Linux/UNIX 系统中,grep、sed、awk 被称为 Shell 编程的 “三剑客”,下面重点介绍 sed 和 awk 这两个强大的文本处理器。

(一)sed 工具

sed(Stream EDitor)是一款强大且简单的文本解析转换工具,可读取文本,并依据指定条件对文本内容进行编辑(如删除、替换、添加、移动等),最后输出所有行或仅输出处理后的某些行。sed 常用于 Shell 脚本,以完成各种自动化处理任务。

  1. 工作流程与命令选项:sed 的工作流程包含读取、执行和显示三个过程。读取时,sed 从输入流(文件、管道、标准输入)读取一行内容并存储到临时缓冲区(模式空间);执行阶段,默认所有 sed 命令在模式空间顺序执行,除非指定行地址;显示过程则将修改后的内容发送到输出流,之后模式空间被清空。常见的 sed 命令选项包括:“-e” 或 “-expression=”,用于指定命令或脚本来处理输入文本文件;“-f” 或 “-file=”,表示用指定的脚本文件处理输入文本文件;“-h” 或 “--help”,用于显示帮助信息;“-n”、“--quiet” 或 “silent”,仅显示处理后的结果;“-i”,直接编辑文本文件。
  2. 用法示例:以 test.txt 文件为例:
“sed -n 'p' test.txt” 	#可输出所有内容,等同于 “cat test.txt”;
“sed -n '3p' test.txt” 	#输出第 3 行;
“sed -n '3,5p' test.txt” 	#输出 3 - 5 行。

结合正则表达式时:

“sed -n '/the/p' test.txt” 	#输出包含 “the” 的行;
“sed -n '/the/=' test.txt”	#输出包含 “the” 的行所在的行号。

在删除操作方面,如:

“sed '3d'” 												#删除第 3 行;
“sed '3,5d'” 											#删除 3 - 5 行;
“sed '/cross/d'” 									#删除包含 “cross” 的行。
“sed '/^[a - z]/d' test.txt”		 	#删除以小写字母开头的行
“sed '/./d' test.txt”							#删除以 “.” 结尾的行
“sed -e '/^/{n;/^/d}' test.txt” 	#删除重复的空行 其效果与“cat -s test.txt”相同

替换操作中:

“sed 's/the/THE/' test.txt”		#将每行中的第一个“the”替换为“THE”;
“sed 's/the/THE/g' test.txt”	#将文件中的所有“the”替换为“THE”;
“sed 's/o//g' test.txt”				#将文件中的所有“o”删除(替换为空串)。

迁移操作时:

“sed '/the/{H;d};G' test.txt” 		#将包含 “the” 的行迁移至文件末尾;
“sed '/the/w out.file' test.txt”  #将包含 “the” 的行另存为文件 out.file。

此外,复杂操作可通过脚本文件实现。例如,将第 1 - 5 行内容转移至第 17 行后,可先创建脚本文件 opt.list,内容为 “1,5H”“1,5d”“17G”,再执行 “sed -f opt.list test.txt”。

  1. 案例:编写脚本调整 vsftpd 服务配置,禁止匿名用户,允许本地用户(也允许写入)。示例脚本如下:
#!/bin/bash
# 指定样本文件路径、配置文件路径
SAMPLE="/usr/share/doc/vsftpd - 3.0.2/EXAMPLE/INTERNET_SITE/vsftpd.conf"
CONFIG="/etc/vsftpd/vsftpd.conf"
# 备份原来的配置文件,检测文件名为/etc/vsftpd/vsftpd.conf.bak备份文件是否存在,若不存在则使用cp命令进行文件备份
[! -e "$CONFIG.bak" ] && cp $CONFIG $CONFIG.bak
# 基于样本配置进行调整,覆盖现有文件
sed -e '/anonymous_enable/s/YES/NO/g' $SAMPLE > $CONFIG
sed -i -e '/^local_enable/s/NO/YES/g' -e '/write_enable/s/NO/YES/g' $CONFIG
grep "listen" $CONFIG || sed -i '\alisten=YES' $CONFIG
# 启动vsftpd服务,并设为开机后自动运行
systemctl restart vsftpd
systemctl enable vsftpd

(二)awk 工具

awk 是 Linux/UNIX 系统中功能强大的编辑工具,可逐行读取输入文本,根据指定的匹配模式进行查找,对符合条件的内容进行格式化输出或过滤处理,广泛应用于 Shell 脚本以完成自动化配置任务。

  1. 命令格式与基本概念:awk 的命令格式为:

“awk 选项 ' 模式或条件 {编辑指令}' 文件 1 文件 2...”,也可通过 “-f” 读取脚本对目标文件进行处理。

awk 倾向于将一行分成多个 “字段” 进行处理,默认字段分隔符为空格或 tab 键,执行结果可通过 print 功能打印显示。awk 还支持逻辑操作符:“&&”(表示 “与”)、“||”(表示 “或”)、“!”(表示 “非”)以及简单的数学运算(如 +、-、*、/、%、^ 分别表示加、减、乘、除、取余和乘方)。
awk 包含几个特殊的内建变量:

  • FS(指定每行文本的字段分隔符,默认为空格或制表位)
  • NF(当前处理的行的字段个数)
  • NR(当前处理的行的行号)
  • $0(当前处理的行的整行内容)
  • $n(当前处理行的第 n 个字段)
  • FILENAME(被处理的文件名)
  • RS(数据记录分隔,默认为 \n,即每行为一条记录)
  1. 用法示例:按行输出文本时:
“awk '{print}' test.txt”    						#或 “awk '{print 0}' test.txt”输出所有内容
“awk 'NR1,NR3{print}'				            #test.txt”输出1 - 3行内容
“awk 'BEGIN {x=0};/\/bin\/bash/{x++};END {print x}' /etc/passwd”  #统计以 “/bin/bash” 结尾的行数。

按字段输出文本时:

“awk '{print $3}' test.txt”												#输出每行中(以空格或制表位分隔)的第3个字段
“awk -F ":" '$7~"/bash"{print $1}' /etc/passwd” 	#输出以冒号分隔且第 7 个字段中包含 “/bash” 的行的第 1 个字段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值