[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 练习
- 
在
/etc/passwd中查找所有以root开头的行。 - 
从
ifconfig或ip a的输出中提取 IPv4 地址。 - 
在
access.log中查找所有包含POST的请求。 
7.2 sed 练习
- 
将
/etc/app.conf文件中的端口8080替换为9090。 - 
删除
test.txt文件中所有空行。 - 
删除
nginx.conf文件中所有以#开头的注释行。 
7.3 awk 练习
- 
打印
/etc/passwd文件中的用户名和默认 shell(第 1 列和第 7 列)。 - 
统计
access.log中每个 IP 出现的次数,并按从大到小排序。 - 
统计
access.log中不同状态码的数量。 
7.4 综合练习(小脚本)
编写一个脚本 log_analyzer.sh,实现以下功能:
- 
提取访问次数最多的前 5 个 IP
 - 
提取所有 500 错误的请求
 - 
统计 200、404、500 各类状态码的数量
 
8. 练习题与参考答案
8.1 grep 练习
题目
- 
在
/etc/passwd中查找所有以root开头的行。 - 
从
ifconfig或ip a的输出中提取 IPv4 地址。 - 
在
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 练习
题目
- 
将
/etc/app.conf文件中的端口8080替换为9090。 - 
删除
test.txt文件中所有空行。 - 
删除
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 练习
题目
- 
打印
/etc/passwd文件中的用户名和默认 shell(第 1 列和第 7 列)。 - 
统计
access.log中每个 IP 出现的次数,并按从大到小排序。 - 
统计
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