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


1. 正则表达式基础

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

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

  • 提取配置文件参数

  • 文本批量替换

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

常见元字符

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

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. ifconfigip 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. ifconfigip 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
相关推荐
叁仟叁佰6 小时前
Shell脚本编程:函数、数组与正则表达式详解
运维·服务器·网络·chrome·正则表达式
Gary Studio7 小时前
Linux-驱动积累
linux
电气铺二表姐137744166157 小时前
【WIFI电表】物联网无线通讯光伏储能三相单相智能电表
运维·人工智能·能源
lin张8 小时前
函数、数组与 grep + 正则表达式的 Linux Shell 编程进阶指南
linux·运维
苏三福9 小时前
交叉编译linux-arm32位程序
linux·运维·服务器
Lin南舟9 小时前
掌握正则表达式与文本处理:提升 Shell 编程效率的关键技巧
linux·正则表达式
青瓦梦滋10 小时前
Linux基本工具(yum、vim、gcc、Makefile、git、gdb)
linux·运维·服务器·c++
梅坞茶坊11 小时前
Centos安装unoconv文档转换工具并在PHP中使用phpword替换word模板中的变量后,使用unoconv将word转换成pdf
linux·服务器·centos
2004v200411 小时前
交叉编译 手动安装 libzip 库 移植ARM 需要 zlib的
linux·运维·arm开发