强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

AWK & SED 生产力教程 / 第 1 章:AWK/SED 入门导论

第 1 章:AWK/SED 入门导论

每一个 Unix 工具都遵循一个哲学:做一件事,并把它做好。AWK 和 SED 是这个哲学最完美的诠释。

1.1 历史渊源

SED 的诞生

SED(Stream EDitor,流编辑器)诞生于 1974 年,由贝尔实验室的 Lee McMahon 开发。它是最早的 Unix 文本处理工具之一,设计初衷是成为 ed 行编辑器的流式版本。

时间线:
1969  Unix 诞生(Ken Thompson, Dennis Ritchie)
1973  ed 编辑器成熟
1974  SED 诞生(Lee McMahon)
1977  AWK 诞生(Aho, Weinberger, Kernighan)
1985  Perl 诞生(Larry Wall,受 AWK 影响)
2004  GNU sed 4.0 发布

AWK 的诞生

AWK 于 1977 年在贝尔实验室诞生,名字来源于三位创造者的姓氏首字母:

字母创造者贡献
AAlfred Aho编译器理论,正则表达式
WPeter Weinberger数据库系统
KBrian KernighanC 语言联合创造者,《AWK 程序设计语言》作者

AWK 最初的设计目标是:让程序员能够在命令行上用一行代码完成数据提取和格式化

💡 趣闻:Brian Kernighan 后来承认,他从未想到 AWK 会被使用超过 40 年。但它的设计简洁到"恰到好处",至今仍是文本处理的标准工具。

1.2 设计哲学

Unix 管道哲学

          stdin          stdout
数据  →  [SED]  →  [AWK]  →  [sort]  →  [uniq]  →  结果
   流式处理,每个工具专注一件事

Unix 工具的核心理念:

原则说明体现
单一职责每个工具只做一件事SED 编辑流,AWK 格式化输出
组合使用通过管道连接`cat file
文本接口一切皆文本输入输出都是文本流
沉默是金没有错误就是成功只输出有结果的内容

SED 的设计哲学

SED 是一个面向行的流编辑器:

输入流 → 逐行读取 → 对匹配行执行命令 → 输出
         ↑
    不修改原文件(除非 -i)

核心设计:

  • 流式处理:一次读一行,处理完就输出,不占用额外内存
  • 非交互式:适合脚本和管道中使用
  • 原地编辑-i 选项可以直接修改文件

AWK 的设计哲学

AWK 是一个面向数据的文本处理语言:

输入 → 分割成字段 → 模式匹配 → 执行动作 → 格式化输出
        ↑
   自动解析结构化文本

核心设计:

  • 数据驱动:根据数据模式决定执行什么操作
  • 字段自动分割:自动将每行拆分成字段
  • 隐式循环:自动对每一行执行规则

1.3 适用场景

SED 最擅长的事

场景示例命令
批量替换把配置文件中的端口改掉sed -i 's/8080/9090/g' config.yml
删除行去掉空行和注释sed '/^#/d; /^$/d' file
插入内容在文件头部添加说明sed '1i\# Auto-generated' file
原地编辑修改多个文件sed -i 's/old/new/g' *.conf
提取行段截取两个标记之间的内容sed -n '/START/,/END/p' file

AWK 最擅长的事

场景示例命令
字段处理提取日志中的 IP 和状态码awk '{print $1, $9}' access.log
统计汇总计算某列的总和/平均值awk '{sum+=$3} END{print sum}' data.csv
条件过滤筛选错误日志awk '$9 >= 500' access.log
报表生成格式化输出数据awk '{printf "%-20s %10d\n", $1, $2}'
数据转换CSV 转 TSVawk -F, '{OFS="\t"; $1=$1}1' file.csv

何时用 SED,何时用 AWK?

需要做的事 →
  只做简单的替换/删除? → SED
  需要处理字段(列)? → AWK
  需要统计/计算? → AWK
  需要复杂的条件判断? → AWK(或 Python)
  需要逐行正则替换? → SED
  需要两者结合? → 管道连接

1.4 与 Python 的对比

相同任务的不同写法

任务 1:统计文件行数

# SED
sed -n '$=' file.txt

# AWK
awk 'END{print NR}' file.txt

# Python
python3 -c "
count = 0
with open('file.txt') as f:
    for _ in f:
        count += 1
print(count)
"

任务 2:提取日志中的 IP 地址并统计出现次数

# AWK(一行搞定)
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# Python(需要更多代码)
python3 -c "
from collections import Counter
with open('access.log') as f:
    ips = [line.split()[0] for line in f]
for ip, count in Counter(ips).most_common(10):
    print(f'{count:>8} {ip}')
"

任务 3:将 CSV 中价格大于 100 的行提取出来

# AWK
awk -F, '$3 > 100' products.csv

# Python
python3 -c "
import csv
with open('products.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        if float(row[2]) > 100:
            print(','.join(row))
"

性能对比

处理一个 1GB 的日志文件(约 1000 万行):

操作AWK/SEDPython说明
简单过滤3-5 秒8-12 秒AWK 快 2-3 倍
字段提取4-6 秒10-15 秒AWK 自动分割优势
正则替换5-8 秒12-18 秒SED 流式处理优势
复杂统计8-15 秒6-10 秒Python 可能更快
多步处理15-25 秒10-15 秒Python 单进程更优

💡 经验法则:行数多、逻辑简单的任务用 AWK/SED;逻辑复杂、需要数据结构的任务用 Python。

选择建议

                  ┌─ 一行命令/管道?──→ AWK/SED
                  │
你的需求是什么?──→├─ 处理结构化数据(JSON/XML)?──→ Python
                  │
                  ├─ 需要错误处理/日志/测试?──→ Python
                  │
                  └─ 系统管理/DevOps 自动化?──→ AWK/SED + Shell

1.5 快速上手

你的第一个 SED 命令

# 创建测试文件
echo -e "Hello World\nHello Linux\nGoodbye World" > hello.txt

# 将 Hello 替换为 Hi
$ sed 's/Hello/Hi/' hello.txt
→ Hi World
→ Hi Linux
→ Goodbye World

你的第一个 AWK 命令

# 创建测试文件
echo -e "Alice 90 85 92\nBob 78 82 88\nCarol 95 91 87" > scores.txt

# 打印每行的第一列(名字)和第三列(第二门成绩)
$ awk '{print $1, $3}' scores.txt
→ Alice 85
→ Bob 82
→ Carol 91

一个实用的管道组合

# 统计当前目录下各类型文件的数量
$ find . -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn
125 md
42 html
18 css
7 js

分解:

  1. find . -type f — 列出所有文件
  2. sed 's/.*\.//' — 提取文件扩展名
  3. sort — 排序(uniq 需要有序输入)
  4. uniq -c — 统计每种扩展名出现次数
  5. sort -rn — 按数量降序排列

1.6 版本差异速查

GNU vs BSD 差异

特性GNU (Linux)BSD (macOS)建议
SED 原地编辑sed -i 's/old/new/' filesed -i '' 's/old/new/' filemacOS 需要空字符串参数
SED 扩展正则sed -Esed -rsed -E-E 最兼容
AWK 版本gawknawk / awk复杂功能用 gawk
AWK 数组关联数组关联数组相同
AWK 函数自定义函数自定义函数相同

⚠️ macOS 用户注意:安装 GNU 工具后建议设置别名,避免踩坑:

brew install gnu-sed gawk
echo 'alias sed="gsed"' >> ~/.zshrc
echo 'alias awk="gawk"' >> ~/.zshrc

1.7 学习建议

学习路径

Week 1: SED 基础 → AWK 基础 → 正则表达式
         ↓
Week 2: SED 进阶 → AWK 进阶 → 文本处理实战
         ↓
Week 3: 管道组合 → 日志分析 → 报告生成
         ↓
Week 4: 脚本编写 → 性能优化 → 最佳实践

学习方法

  1. 动手为王:每个示例都要亲手敲一遍
  2. 从小处开始:先用一个命令解决一个小问题
  3. 管道思维:把复杂问题分解成多个简单步骤
  4. 查阅手册man awkman sedinfo awk 是最好的参考
  5. 积累片段:建立自己的常用命令片段库

📌 记住:不需要记住所有语法,只需要知道"能做什么",细节查手册即可。

扩展阅读


下一章:第 2 章:SED 基础 — 掌握流编辑器的核心操作。