AWK 与 Sed 文本处理教程
AWK 和 Sed 是 Linux 系统中最强大的文本处理工具。AWK 擅长按列提取和处理结构化数据,Sed 则专注于流式文本编辑与替换。在搬瓦工 VPS 的日常运维中,无论是分析 Nginx 访问日志、处理配置文件还是批量修改文本,这两个工具都不可或缺。本教程将全面讲解它们的语法和实际应用。
一、AWK 基础
1.1 AWK 工作原理
AWK 逐行读取输入,按分隔符将每行拆分为字段($1、$2...),然后对满足条件的行执行指定操作。基本语法为:
awk '模式 { 动作 }' 文件名
1.2 字段提取
# 打印第 1 和第 3 列
awk '{print $1, $3}' data.txt
# 指定分隔符为冒号
awk -F: '{print $1, $3}' /etc/passwd
# 打印最后一列
awk '{print $NF}' data.txt
# 打印倒数第二列
awk '{print $(NF-1)}' data.txt
# 打印整行
awk '{print $0}' data.txt
1.3 内置变量
# NR: 当前行号 NF: 当前行字段数 FS: 输入分隔符 OFS: 输出分隔符
awk '{print NR, NF, $0}' data.txt
# 设置输出分隔符
awk -F: 'BEGIN{OFS="\t"} {print $1, $3, $7}' /etc/passwd
# FILENAME: 当前文件名
awk '{print FILENAME, NR, $0}' file1.txt file2.txt
1.4 条件过滤
# 打印第 3 列大于 1000 的行
awk -F: '$3 > 1000 {print $1, $3}' /etc/passwd
# 正则匹配
awk '/error/ {print}' /var/log/syslog
# 指定字段匹配
awk '$9 == 404 {print $7}' access.log
# 多条件组合
awk '$9 >= 400 && $9 < 500 {print $7, $9}' access.log
# 打印行号范围
awk 'NR>=10 && NR<=20' data.txt
二、AWK 高级用法
2.1 BEGIN 和 END 块
# 统计文件行数
awk 'END{print NR}' data.txt
# 计算总和与平均值
awk '{sum += $3; count++} END{print "总和:", sum, "平均:", sum/count}' data.txt
# 添加表头
awk 'BEGIN{print "用户名\tUID\tShell"} -F: {print $1"\t"$3"\t"$7}' /etc/passwd
2.2 Nginx 日志分析实例
# 统计各 IP 访问次数(Top 10)
awk '{count[$1]++} END{for(ip in count) print count[ip], ip}' access.log | sort -rn | head -10
# 统计各状态码分布
awk '{count[$9]++} END{for(code in count) print code, count[code]}' access.log | sort -k2 -rn
# 统计每小时请求量
awk '{split($4, a, ":"); hour=a[2]; count[hour]++} END{for(h in count) print h":00", count[h]}' access.log | sort
# 查找慢请求(响应时间超过 3 秒)
awk '$NF > 3.0 {print $7, $NF"s"}' access.log
2.3 数组与函数
# 关联数组实现词频统计
awk '{for(i=1;i<=NF;i++) words[$i]++} END{for(w in words) print words[w], w}' text.txt | sort -rn | head -20
# 字符串函数
awk '{print toupper($1), length($0)}' data.txt
awk '{sub(/old/, "new"); print}' data.txt
awk '{gsub(/[0-9]+/, "NUM"); print}' data.txt
# substr 截取子串
awk '{print substr($0, 1, 50)}' data.txt
三、Sed 基础
3.1 Sed 工作原理
Sed(Stream Editor)是流编辑器,逐行处理文本,默认将结果输出到标准输出,不修改原文件。基本语法为:
sed '命令' 文件名
3.2 文本替换
# 基本替换(每行第一个匹配)
sed 's/old/new/' file.txt
# 全局替换(每行所有匹配)
sed 's/old/new/g' file.txt
# 忽略大小写替换
sed 's/error/WARNING/gi' log.txt
# 直接修改文件(-i 选项)
sed -i 's/old/new/g' file.txt
# 创建备份后修改
sed -i.bak 's/old/new/g' file.txt
# 使用不同分隔符(处理路径时很方便)
sed 's|/usr/local|/opt|g' config.txt
3.3 行操作
# 删除指定行
sed '3d' file.txt # 删除第 3 行
sed '2,5d' file.txt # 删除第 2 到第 5 行
sed '/^#/d' file.txt # 删除注释行
sed '/^$/d' file.txt # 删除空行
# 插入和追加
sed '3i\新插入的行' file.txt # 在第 3 行前插入
sed '3a\新追加的行' file.txt # 在第 3 行后追加
# 打印指定行
sed -n '5p' file.txt # 只打印第 5 行
sed -n '10,20p' file.txt # 打印第 10 到 20 行
sed -n '/pattern/p' file.txt # 打印匹配行
3.4 高级替换
# 使用捕获组(反向引用)
sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\3\/\2\/\1/' date.txt
# 使用扩展正则(-E 选项更简洁)
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/' date.txt
# 只在匹配行执行替换
sed '/^server/s/80/443/g' nginx.conf
# 替换某个范围内的文本
sed '10,20s/foo/bar/g' file.txt
四、Sed 实用示例
4.1 配置文件编辑
# 修改 SSH 端口
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
sed -i 's/^Port 22/Port 2222/' /etc/ssh/sshd_config
# 禁用 root 登录
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 修改 Nginx 配置中的域名
sed -i 's/server_name old.example.com/server_name new.example.com/g' /etc/nginx/conf.d/site.conf
# 在配置文件特定位置添加内容
sed -i '/\[mysqld\]/a\max_connections = 500' /etc/mysql/my.cnf
4.2 批量文件处理
# 批量替换多个文件中的内容
find /var/www -name "*.html" -exec sed -i 's/http:/https:/g' {} \;
# 去除 Windows 换行符
sed -i 's/\r$//' script.sh
# 在每行末尾添加内容
sed 's/$/ \\/' file.txt
# 提取两个标记之间的内容
sed -n '/BEGIN/,/END/p' file.txt
五、AWK 与 Sed 组合使用
# 分析 Nginx 日志:提取 404 错误的 URL 并去重统计
awk '$9 == 404 {print $7}' access.log | sed 's/?.*//' | sort | uniq -c | sort -rn | head -20
# 提取 IP 并检查是否在黑名单中
awk '{print $1}' access.log | sort -u | while read IP; do
if grep -q "$IP" blacklist.txt; then
echo "拦截: $IP"
fi
done
# 生成 Nginx deny 规则
awk '{count[$1]++} END{for(ip in count) if(count[ip]>1000) print ip}' access.log | \
sed 's/^/deny /' | sed 's/$/;/'
# 清理日志并提取关键信息
cat /var/log/auth.log | sed 's/\s\+/ /g' | awk '/Failed password/ {print $11}' | sort | uniq -c | sort -rn
六、性能优化技巧
# 处理大文件时使用 LC_ALL=C 加速
LC_ALL=C awk '{print $1}' large_file.log
# 避免不必要的管道,AWK 可以替代 grep + cut 组合
# 低效写法
grep "ERROR" log.txt | cut -d' ' -f3
# 高效写法
awk '/ERROR/ {print $3}' log.txt
# Sed 处理大文件时只处理特定行范围
sed -n '1000000,1000100p' huge_file.txt
总结
AWK 和 Sed 是 Linux 文本处理的两大利器。AWK 适合结构化数据的提取与统计分析,Sed 适合文本的流式编辑与替换。在搬瓦工 VPS 运维中,熟练使用这两个工具可以大幅提升日志分析和配置管理效率。建议同时学习 Grep 正则表达式 和 Bash 脚本编程,构建完整的文本处理能力。选购搬瓦工 VPS 请查看全部方案,使用优惠码 NODESEEK2026 可享受 6.77% 循环折扣。