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
相关推荐
蓁蓁啊2 小时前
GIT使用SSH 多账户配置
运维·git·ssh
路由侠内网穿透5 小时前
本地部署开源持续集成和持续部署系统 Woodpecker CI 并实现外部访问
服务器·网络·windows·ci/cd·开源
程序猿小三5 小时前
Linux下基于关键词文件搜索
linux·运维·服务器
虚拟指尖6 小时前
Ubuntu编译安装COLMAP【实测编译成功】
linux·运维·ubuntu
椎4957 小时前
苍穹外卖前端nginx错误之一解决
运维·前端·nginx
刘某的Cloud7 小时前
parted磁盘管理
linux·运维·系统·parted
啊?啊?7 小时前
4 解锁 Linux 操作新姿势:man、grep、tar ,创建用户及添加权限等 10 大实用命令详解
linux·服务器·实用指令
程序员老舅7 小时前
干货|腾讯 Linux C/C++ 后端开发岗面试
linux·c语言·c++·编程·大厂面试题
极验7 小时前
iPhone17实体卡槽消失?eSIM 普及下的安全挑战与应对
大数据·运维·安全
爱倒腾的老唐7 小时前
24、Linux 路由管理
linux·运维·网络