1. 正则表达式基础
1.1 什么是正则表达式?
正则表达式(Regular Expression,简称 regex/regexp/RE)是一种用于描述字符串模式的规则系统。它通过特定的元字符和语法规则,能够高效地进行字符串的检索、替换和过滤操作。
1.2 正则表达式的主要用途
-
系统日志分析:快速定位如"登录失败"、"服务启动失败"等关键信息
-
配置文件解析:提取或修改特定格式的配置项
-
文本查找与替换:批量处理文本内容
-
脚本编程:在 Shell 脚本中实现复杂的条件匹配
1.3 Linux 中的正则表达式分类
1.3.1 基础正则表达式(BRE)
-
传统正则表达式语法,功能相对有限
-
量词
{}需要转义为\{n,m\} -
+,?,()等特殊字符需要转义 -
常用工具:
grep、sed(默认模式)
1.3.2 扩展正则表达式(ERE)
-
功能更强大,语法更简洁
-
+,?,(),{},|等元字符无需转义 -
常用工具:
egrep(或grep -E)、awk
1.4 正则表达式组成元素
1.4.1 普通字符
字母、数字、标点符号等普通字符,匹配它们自身。
1.4.2 元字符
-
.:匹配任意单个字符(除换行符\r\n外) -
[]:匹配字符集合中的任意一个字符,如[a-z],[0-9],[A-Z] -
[^]:匹配不在指定字符集合中的任意一个字符 -
^:匹配行首位置 -
$:匹配行尾位置 -
\:转义字符,用于取消元字符的特殊含义
1.4.3 重复次数限定符
-
*:匹配前面的子表达式 0 次或多次 -
\+:匹配前面的子表达式至少 1 次 -
\{n\}:匹配前面的子表达式恰好 n 次 -
\{n,m\}:匹配前面的子表达式 n 到 m 次 -
\{n,\}:匹配前面的子表达式至少 n 次
1.4.4 扩展正则表达式特有元字符
-
+:匹配前面的子表达式 1 次或多次 -
?:匹配前面的子表达式 0 次或 1 次 -
|:或操作,匹配多个模式中的任意一个 -
():分组,将多个模式组合为一个单元 -
()+:匹配重复的组模式
2. grep 工具:条件查找利器
2.1 常用选项
-
-E:启用扩展正则表达式 -
-c:统计匹配行的数量 -
-i:忽略大小写进行匹配 -
-o:只输出匹配的内容 -
-v:反向匹配,输出不包含模式的行 -
-n:显示匹配行的行号 -
--color=auto:高亮显示匹配内容
2.2 使用示例
统计包含 root 的行数 grep -c root /etc/passwd 不区分大小写匹配 the grep -i "the" web.sh 输出不包含 root 的行 grep -v root /etc/passwd 提取 IP 地址 grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' ifconfig.out | head -1
3. sed:流编辑器深度解析
3.1 什么是 sed?
sed(Stream Editor)是一种流式文本编辑器,它能够根据预先提供的脚本指令来处理、编辑文本文件。sed 主要用于自动化编辑一个或多个文件、简化重复性文件操作以及编写文本转换程序。
3.2 sed 的工作原理
sed 的工作流程包含三个核心步骤:
-
读取:从输入流(文件、管道或标准输入)中读取一行内容到模式空间(pattern space)
-
执行:按顺序执行所有 sed 命令,除非指定了行地址限制
-
显示:将处理后的内容发送到输出流,然后清空模式空间
特别注意:默认情况下,sed 不会直接修改源文件,所有操作都在模式空间中进行,处理结果输出到标准输出。如需修改源文件,需使用 -i 选项。
3.3 sed 命令语法
sed [选项] '操作' 文件 sed [选项] -f 脚本文件 文件
3.4 常用选项
-
-e:允许多个编辑指令 -
-f:指定包含 sed 脚本的文件 -
-n:抑制默认输出,只显示处理后的结果 -
-i[扩展名]:直接编辑文件(可选的扩展名用于备份原文件) -
-r或-E:使用扩展正则表达式
3.5 常用操作命令
-
p:打印模式空间的内容 -
d:删除模式空间的内容 -
s/模式/替换/标志:替换操作 -
a\文本:在指定行后追加文本 -
i\文本:在指定行前插入文本 -
c\文本:替换整行内容 -
y/原字符/目标字符/:字符转换
3.6 sed 使用示例
3.6.1 输出特定内容
输出第3行 sed -n '3p' demo.txt 输出3-5行 sed -n '3,5p' demo.txt 输出所有奇数行 sed -n 'p;n' demo.txt 输出包含"the"的行 sed -n '/the/p' demo.txt
3.6.2 删除特定内容
删除第3行 nl demo.txt | sed '3d' 删除3-5行 nl demo.txt | sed '3,5d' 删除包含"cross"的行 nl demo.txt | sed '/cross/d'
3.6.3 替换文本内容
将每行第一个"the"替换为"THE" sed 's/the/THE/' demo.txt 将全局所有"the"替换为"THE" sed 's/the/THE/g' demo.txt 将3-5行中的所有"the"替换为"THE" sed '3,5s/the/THE/g' demo.txt
3.6.4 迁移和插入文本
将包含"the"的行迁移至文件末尾
sed '/the/{H;d};$G' demo.txt
在第3行后插入新行
sed '3a\New Line' demo.txt
在包含"the"的每行后插入新行
sed '/the/a\New Line' demo.txt
3.7 生产环境应用案例
案例1:修改网络配置
将ens33接口的IP地址修改为192.168.10.100 sed -i 's/^IPADDR=.*/IPADDR=192.168.10.100/' /etc/sysconfig/network-scripts/ifcfg-ens33
案例2:调整Apache配置
修改监听地址和端口 sudo sed -i 's/^Listen .*/Listen 192.168.10.100:8080/' /etc/httpd/conf/httpd.conf 修改服务器名 sed -i 's/^#ServerName .*/ServerName 192.168.10.100:8080/' /etc/httpd/conf/httpd.conf
案例3:自动化配置vsftpd服务
#!/bin/bash 配置vsftpd服务:禁止匿名用户,允许本地用户写入 SAMPLE="/usr/share/doc/vsftpd-3.0.2/EXAMPLE/INTERNET_SITE/vsftpd.conf" CONFIG="/etc/vsftpd/vsftpd.conf" 备份原配置文件 [ ! -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 '$a\listen=YES' $CONFIG 重启服务 systemctl restart vsftpd systemctl enable vsftpd
4. 高级技巧与最佳实践
4.1 分组操作
当需要对一行数据执行多个操作时,可以使用分组功能:
多次替换操作
sed '/root/ {s/root/ROOT/; s/bash/BASH/}' /etc/passwd
使用分组提取IP地址
ifconfig ens33 | sed -rn '2s/.*inet ([0-9.]+).*/\1/p'
4.2 使用脚本文件
对于复杂的sed操作,可以将其保存到脚本文件中:
创建sed脚本
cat > script.sed << EOF
1,5 {
H
d
}
16G
EOF
使用脚本文件处理文本
sed -f script.sed demo.txt
4.3 性能优化建议
-
减少回溯:编写精确的正则表达式,避免过度使用通配符
-
使用地址限定:尽可能指定操作的行范围,减少不必要的处理
-
合并操作:将多个操作合并到一个sed命令中,减少IO开销
-
避免不必要的捕获组:只捕获需要的内容,提高匹配效率
5. 总结
正则表达式和sed是Shell编程中极其强大的文本处理工具组合。通过本文的详细讲解,我们了解到:
-
正则表达式提供了强大的模式匹配能力,分为基础正则表达式和扩展正则表达式两种类型,各自适用于不同的场景和工具。
-
grep是基于正则表达式的文本搜索工具,适合快速查找和过滤文本内容。
-
sed作为流编辑器,不仅支持模式匹配,还提供了丰富的文本转换功能,包括删除、替换、插入、迁移等操作。
-
在实际生产环境中,sed常用于批量修改配置文件、日志处理、数据提取等任务,结合正则表达式可以实现高度自动化的文本处理流程。
-
掌握分组操作、脚本文件和性能优化技巧,能够大幅提高文本处理的效率和准确性。
正则表达式和sed的学习曲线可能较陡峭,但一旦掌握,它们将成为日常系统管理和软件开发中不可或缺的利器。建议通过实际案例不断练习,逐步熟悉各种元字符和命令选项的用法,最终达到熟练运用的水平。
980

被折叠的 条评论
为什么被折叠?



