Shell 编程 —— 正则表达式与文本处理实战

前言

[1. 正则表达式基础](#1. 正则表达式基础)

常见元字符

[2. grep ------ 文本查找](#2. grep —— 文本查找)

常用选项

示例

[3. sed ------ 文本替换与编辑](#3. sed —— 文本替换与编辑)

示例

[4. awk ------ 文本分析与报表](#4. awk —— 文本分析与报表)

示例

[5. 实战案例:Nginx 日志分析](#5. 实战案例:Nginx 日志分析)

[5.1 访问最多的前 10 个 IP](#5.1 访问最多的前 10 个 IP)

[5.2 查找 404 错误请求](#5.2 查找 404 错误请求)

[5.3 统计状态码分布](#5.3 统计状态码分布)

[5.4 最终脚本](#5.4 最终脚本)

[6. 总结](#6. 总结)

[7. 练习题](#7. 练习题)

[7.1 grep 练习](#7.1 grep 练习)

[7.2 sed 练习](#7.2 sed 练习)

[7.3 awk 练习](#7.3 awk 练习)

[7.4 综合练习(小脚本)](#7.4 综合练习(小脚本))

[8. 练习题与参考答案](#8. 练习题与参考答案)

[8.1 grep 练习](#8.1 grep 练习)

8[.2 sed 练习](#.2 sed 练习)

8[.3 awk 练习](#.3 awk 练习)

8[.4 综合练习(小脚本)](#.4 综合练习(小脚本))

前言

在 Linux 运维和开发中,正则表达式 是一个必不可少的工具。它能帮助我们快速处理日志、配置文件和大批量文本。本文将通过 grep、sed、awk 的结合使用,带你全面掌握常见的正则技巧,并给出实战案例。


1. 正则表达式基础

正则表达式(Regular Expression, regex)是一种 描述字符串模式的规则,常见用途包括:

  • 日志筛选(查找错误或特定请求)

  • 提取配置文件参数

  • 文本批量替换

  • 数据格式校验(邮箱、手机号等)

常见元字符

符号 含义 示例
. 任意单个字符 a.b → acb, arb
[] 字符集合 [0-9] 匹配数字
[^] 非集合 [^A-Z] 匹配非大写字母
^ 行首 ^ERROR 匹配以 ERROR 开头
$ 行尾 end$ 匹配以 end 结尾
* 0 次或多次 ba* → b, baaa
+ 1 次或多次 (ERE) go+gle → google, gooogle
? 0 或 1 次 (ERE) colou?r → color, colour
{n} 恰好 n 次 [0-9]\{4\} → 4 位数字
{m,n} m 到 n 次 [0-9]\{2,5\} → 2~5 位数字
` ` 或
() 分组 (ab)+ → ab、abab

2. grep ------ 文本查找

grep 是最常用的正则工具,用于查找和过滤文本。

常用选项

  • -E:启用扩展正则

  • -i:忽略大小写

  • -n:显示行号

  • -v:反向匹配

  • -o:只输出匹配部分

示例

复制代码
# 查找以 ERROR 开头的日志 
grep -n '^ERROR' app.log 
# 提取 IPv4 地址 
grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' ifconfig.out 
# 提取邮箱地址 
grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-z]{2,}' users.txt

3. sed ------ 文本替换与编辑

sed 是一个 流编辑器,适合对文件进行批量修改。

示例

复制代码
# 把配置文件里的 8080 改成 9090 
sed -i 's/8080/9090/g' /etc/app.conf 
# 删除空行 
sed '/^$/d' test.txt 
# 提取邮箱所在行 
sed -n '/[a-zA-Z0-9._%+-]\+@[a-zA-Z0-9.-]\+\.[a-z]\{2,4\}/p' users.txt

4. awk ------ 文本分析与报表

awk 擅长处理 结构化文本,比如日志和 CSV 文件。

示例

复制代码
# 打印 /etc/passwd 的用户名 
awk -F: '{print $1}' /etc/passwd 
# 统计每个 IP 的访问次数 
awk '{print $1}' access.log | sort | uniq -c | sort -nr 
# 提取手机号(11 位数字) 
awk '/[0-9]{11}/ {print $0}' users.txt

5. 实战案例:Nginx 日志分析

假设有日志 /var/log/nginx/access.log:

复制代码
192.168.1.10 - - 
[01/Sep/2025:10:12:33 +0800] "GET /index.html HTTP/1.1" 
200 1024 192.168.1.11 - - 
[01/Sep/2025:10:12:35 +0800] "POST /login HTTP/1.1" 404 512 
192.168.1.12 - - 
[01/Sep/2025:10:12:36 +0800] "GET /admin HTTP/1.1" 403 256

5.1 访问最多的前 10 个 IP

复制代码
awk '{print $1}'
access.log | sort | uniq -c | sort -nr | head -10

5.2 查找 404 错误请求

复制代码
grep ' 404 ' access.log

5.3 统计状态码分布

复制代码
awk '{print $9}' 
access.log | sort | uniq -c | sort -nr

5.4 最终脚本

复制代码
#!/bin/bash 
logfile="/var/log/nginx/access.log" 
echo "====== 访问最多的前 10 个 IP ======" 
awk '{print $1}' 
$logfile | sort | uniq -c | sort -nr | head -10 
echo "====== 404 错误请求 ======" 
grep ' 404 ' 
$logfile 
echo "====== 状态码统计 ======" 
awk '{print $9}' 
$logfile | sort | uniq -c | sort -nr

6. 总结

  • grep:查找与过滤

  • sed:替换与编辑

  • awk:字段处理与统计

  • 三者结合,能完成从 日志搜索 → 文本替换 → 报表分析 的完整流程。 🚀

7. 练习题

下面给出一些常见的练习题,建议你在 Linux 环境下实际操作:

7.1 grep 练习

  1. 在 /etc/passwd 中查找所有以 root 开头的行。

  2. 从 ifconfig 或 ip a 的输出中提取 IPv4 地址。

  3. 在 access.log 中查找所有包含 POST 的请求。

7.2 sed 练习

  1. 将 /etc/app.conf 文件中的端口 8080 替换为 9090。

  2. 删除 test.txt 文件中所有空行。

  3. 删除 nginx.conf 文件中所有以 # 开头的注释行。

7.3 awk 练习

  1. 打印 /etc/passwd 文件中的用户名和默认 shell(第 1 列和第 7 列)。

  2. 统计 access.log 中每个 IP 出现的次数,并按从大到小排序。

  3. 统计 access.log 中不同状态码的数量。

7.4 综合练习(小脚本)

编写一个脚本 log_analyzer.sh,实现以下功能:

  • 提取访问次数最多的前 5 个 IP

  • 提取所有 500 错误的请求

  • 统计 200、404、500 各类状态码的数量

8. 练习题与参考答案

8.1 grep 练习

题目

  1. 在 /etc/passwd 中查找所有以 root 开头的行。

  2. 从 ifconfig 或 ip a 的输出中提取 IPv4 地址。

  3. 在 access.log 中查找所有包含 POST 的请求。

答案

复制代码
# 1. 以 root 开头 
grep '^root' /etc/passwd 
# 2. 提取 IPv4 地址 
ifconfig | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' 
# 3. 查找 POST 请求 
grep 'POST' access.log

8.2 sed 练习

题目

  1. 将 /etc/app.conf 文件中的端口 8080 替换为 9090。

  2. 删除 test.txt 文件中所有空行。

  3. 删除 nginx.conf 文件中所有以 # 开头的注释行。

答案

复制代码
# 1. 替换端口 
sed -i 's/8080/9090/g' /etc/app.conf 
# 2. 删除空行 
sed -i '/^$/d' test.txt 
# 3. 删除注释行 
sed -i '/^#/d' nginx.conf

8.3 awk 练习

题目

  1. 打印 /etc/passwd 文件中的用户名和默认 shell(第 1 列和第 7 列)。

  2. 统计 access.log 中每个 IP 出现的次数,并按从大到小排序。

  3. 统计 access.log 中不同状态码的数量。

答案

复制代码
# 1. 用户名和默认 
shell awk -F: '{print $1, $7}' /etc/passwd 
# 2. 统计 IP 次数 
awk '{print $1}' access.log | sort | uniq -c | sort -nr 
# 3. 统计状态码数量 
awk '{print $9}' access.log | sort | uniq -c | sort -nr

8.4 综合练习(小脚本)

题目

编写一个脚本 log_analyzer.sh,实现以下功能:

  • 提取访问次数最多的前 5 个 IP

  • 提取所有 500 错误的请求

  • 统计 200、404、500 各类状态码的数量

参考脚本

复制代码
#!/bin/bash 
logfile="access.log" 
echo "====== 访问最多的前 5 个 IP ======" 
awk '{print $1}' 
$logfile | sort | uniq -c | sort -nr | head -5 
echo "====== 500 错误请求 ======" 
grep ' 500 ' $logfile 
echo "====== 状态码统计 ======" 
awk '{print $9}' 
$logfile | grep -E '200|404|500' | sort | uniq -c | sort -nr

执行示例:

复制代码
$ bash log_analyzer.sh
 ====== 访问最多的前 5 个 IP ====== 
150 192.168.1.10 120 192.168.1.11 ...
 ====== 500 错误请求 ====== 
192.168.1.12 - - 
[01/Sep/2025:10:12:36 +0800] "GET /admin HTTP/1.1" 500 512 
====== 状态码统计 ====== 
300 200 120 404 50 500
相关推荐
广州灵眸科技有限公司2 小时前
4G 模组开机自连 systemd 服务方案:基于灵眸科技EAI1106--Core-T
运维·服务器·科技
天远数科3 小时前
零信任架构实战:基于天远企业股权变更构建自动化商业银行对公授信存续期股权异动与资产抽逃预警网关
运维·人工智能·架构·自动化
qq_401700413 小时前
Linux设备树详解
linux·运维·服务器
云梦谭4 小时前
让 Linux 主动连接 Windows:配置 Windows 11 SSH 服务端
linux·windows·ssh
奇树谦4 小时前
Windows CMD 下 mc 运维指南:SeaweedFS 安装验收与 MinIO 数据迁移
运维·windows
刚入门的大一新生4 小时前
Linux-信号
linux·运维·服务器
车软学堂4 小时前
CANoe自动化:跑起第一个测试用例
运维·车载系统·自动化·汽车·测试用例
L0208246 小时前
Kubernetes Ingress|CNI 网络模型|Calico 网络策略|Pod 调度器完整实战教程
运维·网络·云原生·容器·kubernetes
考拉讲支付8 小时前
延迟分账 / 核销分账的技术实现方案:服务完成后再分钱,到底怎么设计?
大数据·运维·人工智能·微信小程序·小程序·系统架构