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% 循环折扣。

关于本站

搬瓦工VPS中文网(bwgvps.com)是非官方中文信息站,整理搬瓦工的方案、优惠和教程。我们不销售主机,不提供技术服务。

新手必读
搬瓦工优惠码

NODESEEK2026(优惠 6.77%)

购买时填入即可抵扣。