🔤 第23课:正则表达式

阶段四:Shell脚本第5/6课

📚 课程目标

一、正则类型

类型工具特点
BREgrep/sed默认基本正则,()+需要转义
EREgrep -E/sed -E/awk扩展正则,直接用+()
PCREgrep -P/perl最强大,非POSIX

二、元字符

2.1 匹配字符

语法含义示例
.任意单字符a.c → abc
[abc]字符类[aeiou]
[a-z]范围[0-9]
[^abc]取反[^0-9]
\d数字(PCRE)等同[0-9]
\w单词字符[a-zA-Z0-9_]
\s空白空格/tab

2.2 量词

语法含义示例
*0次或多次ab*c → ac,abc
+1次或多次ab+c → abc
?0或1次colou?r
{n}恰好n次[0-9]{3}
{n,m}n到m次[0-9]{2,4}

2.3 锚点

语法含义
^行首
$行尾
\b单词边界

三、常用正则模式

# IP地址
[0-9]{1,3}(\.[0-9]{1,3}){3}

# 邮箱(简化)
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}

# 手机号(中国)
1[3-9][0-9]{9}

# 日期 YYYY-MM-DD
[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])

# URL
https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}[/\S]*

四、Shell正则应用

# grep
grep -E '1[3-9][0-9]{9}' file         # 手机号
grep -E '[0-9]{1,3}(\.[0-9]{1,3}){3}' log  # IP

# Bash [[ =~ ]]
phone="13812345678"
if [[ $phone =~ ^1[3-9][0-9]{9}$ ]]; then
    echo "有效手机号"
fi

# sed替换
sed -E 's/[0-9]{1,3}(\.[0-9]{1,3}){3}/REDACTED/g' log

# awk匹配
awk '/^[0-9]{4}-[0-9]{2}-[0-9]{2}/' logfile

五、正则性能优化

📋 优化建议

  1. 具体化字符类:用[a-z]代替.
  2. 锚定减少回溯:用^$限制范围
  3. 避免嵌套量词:(a+)+易回溯爆炸
  4. 使用非捕获分组:(?:)代替()

六、实战:数据验证脚本

#!/bin/bash
validate_ip() {
    [[ $1 =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]] || return 1
    local IFS='.'; read -ra o <<< "$1"
    for x in "${o[@]}"; do ((x > 255)) && return 1; done
}

validate_email() {
    [[ $1 =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]
}

validate_ip "192.168.1.1" && echo "IP ✅" || echo "IP ❌"
validate_email "test@example.com" && echo "邮箱 ✅" || echo "邮箱 ❌"

七、练习

📝 正则匹配练习

# 1. 匹配IPv4私有地址
grep -E '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)' file

# 2. 提取HTML标签内容
echo '<title>Hello</title>' | sed 's/<[^>]*>//g'

# 3. 验证日期格式
date="2024-01-15"
[[ $date =~ ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$ ]]
echo "日期验证: $?"
🏆

成就解锁:正则专家

✅ 理解BRE/ERE/PCRE

✅ 掌握元字符与量词

✅ 学会常用模式

✅ 掌握Shell正则

✅ 了解性能优化

八、正则表达式实战案例

# 1. 提取日志中的错误消息
grep -E '\[ERROR\].*' app.log

# 2. 匹配MAC地址
grep -E '([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' file

# 3. 匹配语义版本号
grep -E '[0-9]+\.[0-9]+\.[0-9]+' versions.txt

# 4. 匹配时间戳
grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}' log

# 5. 匹配金额
grep -E '\$[0-9]+(\.[0-9]{2})?' prices.txt

# 6. 匹配十六进制颜色
grep -E '#[0-9A-Fa-f]{6}' styles.css

# 7. 验证域名
grep -E '^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]{2,})+$' domains.txt

九、正则调试工具

# 在线工具
# regex101.com - 支持多语言正则测试
# debuggex.com - 可视化正则表达式

# 命令行调试
# 使用grep -P --color=auto高亮匹配
echo "test 192.168.1.1 end" | grep -P --color=auto '\d{1,3}(\.\d{1,3}){3}'

# sed调试:先不加-i看效果
sed -n 's/pattern/replacement/p' file  # 仅打印替换的行

十、正则与性能

📋 灾难性回溯案例

# 危险!嵌套量词可能导致指数级回溯
# (a+)+ 匹配 "aaaaaaaaaaaaAX" 会非常慢

# 安全写法:具体化匹配
# 用 [a-z]+ 替代 .+
# 用 ^$ 锚定减少搜索空间
# 使用原子分组 (?>...) (PCRE)

附录:正则表达式学习资源

推荐书籍

书名作者重点
Linux命令行与Shell脚本编程大全BlumShell脚本全面覆盖
UNIX/Linux系统管理技术手册Nemeth系统管理圣经
Ansible: Up and RunningLintnerAnsible实战
鸟哥的Linux私房菜鸟哥中文经典入门

在线资源

认证路径

认证机构级别
LFCSLinux Foundation基础系统管理
LFCELinux Foundation高级系统工程师
RHCSARed HatRed Hat管理员
RHCERed HatRed Hat工程师
CKA/CKADCNCFKubernetes管理员/开发者

实践环境

常用速查表

# 文本处理速查
grep -E 'pattern' file     # 扩展正则搜索
sed -i 's/old/new/g' file  # 替换
awk '{print $1}' file     # 提取列
sort | uniq -c | sort -rn   # 频次统计
cut -d: -f1 file            # 切列
tr 'A-Z' 'a-z'             # 转小写

# 系统管理速查
systemctl status/start/stop/restart service
journalctl -u service -f    # 跟踪日志
df -h / du -sh *            # 磁盘使用
ps aux --sort=-%mem         # 内存排序
ss -tlnp                    # 监听端口
iptables -L -n              # 防火墙规则
crontab -e                  # 编辑定时任务
useradd -m -s /bin/bash user # 创建用户

# 网络诊断速查
ip addr / ip route          # 网络配置
ping / traceroute           # 连通测试
dig / nslookup              # DNS查询
curl -I url                 # HTTP头检查
nc -zv host port            # 端口测试
tcpdump -i eth0 port 80     # 抓包

十、实机验证记录

$ echo "test 192.168.1.1 end" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'
192.168.1.1
$ echo "13812345678" | grep -cE '^1[3-9][0-9]{9}$'
1
$ echo "2024-01-15" | grep -cE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'
1

十二、正则生产实践

#!/bin/bash
# 检测SSH暴力破解
detect_bruteforce() {
    journalctl -u sshd 2>/dev/null | \
    grep "Failed password" | \
    grep -oP 'from \K[0-9]+(\.[0-9]+){3}' | \
    sort | uniq -c | sort -rn | \
    awk '$1 > 5 {print "Alert: "$2" failed "$1" times"}'
}

# 解析JSON (grep+sed)
json_value() {
    echo "$1" | grep -oP ""$2"\s*:\s*\K[^\s,}]+"
}

专题:正则表达式引擎原理

在实际生产环境中,正则表达式引擎原理是系统管理员必须深入掌握的核心能力。本节将探讨常见场景、最佳实践和避坑指南。

常见问题与解决方案

问题1:脚本在生产环境运行异常

开发环境和生产环境的差异是脚本出错的常见原因。建议:

问题2:性能不达预期

优化策略:

问题3:可维护性差

改善方法:

最佳实践总结

#!/bin/bash
# 正则表达式引擎原理最佳实践模板
set -euo pipefail

# 1. 参数校验
[[ $# -lt 1 ]] && echo "Usage: $0 <arg>" >&2 && exit 1

# 2. 环境检查
require_cmd() {
    command -v "$1" >/dev/null || { echo "需要: $1" >&2; exit 1; }
}

# 3. 清理机制
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT

# 4. 日志记录
log() { echo "[$(date +%T)] $*"; }
err() { log "ERROR: $*" >&2; exit 1; }

# 5. 主逻辑
main() {
    log "开始处理: $1"
    # 业务逻辑
    log "处理完成"
}

main "$@"

进阶方向

延伸阅读:实用命令速查

# 文件操作
ls -la                    # 详细列表
find / -name "*.conf" 2>/dev/null  # 查找文件
ln -s target link         # 符号链接
du -sh * | sort -rh       # 目录大小排序

# 文本处理
grep -rn "pattern" dir/   # 递归搜索
sed -i.bak 's/old/new/g' f  # 备份替换
awk -F: '{print $1}' file  # 提取列
sort file | uniq -c        # 去重计数

# 系统管理
systemctl status/start/stop/restart service
journalctl -u service -f  # 实时日志
ps aux --sort=-%mem        # 内存排序
ss -tlnp                   # 监听端口
crontab -e                 # 定时任务

# 网络诊断
ip addr/route/show         # 网络配置
ping/traceroute            # 连通测试
dig/nslookup               # DNS查询
curl -I url                # HTTP检查
nc -zv host port           # 端口测试

# 磁盘管理
df -h                      # 磁盘使用
fdisk -l                   # 分区信息
mkfs.ext4 /dev/sdb1        # 格式化
mount /dev/sdb1 /mnt       # 挂载
blkid                      # UUID查看

总结

本章内容是Linux系统管理课程的重要组成部分。掌握这些知识需要大量的实践操作,建议在虚拟机或云服务器上反复练习。记住:纸上得来终觉浅,绝知此事要躬行。

在实际工作中,遇到问题时:

  1. 先看日志(journalctl/dmesg/var/log)
  2. 再查文档(man/info/--help)
  3. 然后搜索(Google/Stack Overflow)
  4. 最后实验(在测试环境验证)