awk 是一种强大的文本处理工具,而 -f 选项是它最核心、最常用的功能之一。

awk -f 的核心作用
awk -f 命令用于从文件中读取 awk 脚本,而不是直接在命令行中编写脚本。
基本语法:
awk -f script_file input_file1 input_file2 ...
awk: 命令本身。-f script_file: 指定一个包含awk脚本的文件。-f是 "file" 的缩写。input_file...: 要处理的文本文件,如果不指定,awk会从标准输入(例如管道)读取数据。
为什么需要 -f 选项?
虽然 awk 支持直接在命令行写脚本,
awk '{print $1, $3}' data.txt
但当脚本变得复杂时(包含多个 BEGIN/END 块、if 条件、for 循环、函数等),在命令行中输入会变得非常困难和难以管理。

使用 -f 选项将脚本与命令分离,带来了以下巨大好处:
- 可读性强: 脚本文件有清晰的格式和缩进,易于阅读和理解。
- 可维护性高: 当需要修改脚本逻辑时,只需编辑脚本文件,而不需要重新输入一长串命令。
- 可重用性: 同一个脚本文件可以应用于不同的数据文件,实现了代码的复用。
- 便于调试: 可以像普通程序一样编辑和测试脚本文件。
-f 选项的工作原理
当您使用 awk -f my_script.awk data.txt 时,awk 会执行以下操作:
- 读取脚本文件:
awk首先打开并读取my_script.awk文件的内容。 - 解析脚本: 它会解析文件中的所有指令,构建一个内部的程序结构。
- 处理输入文件:
awk会逐行读取data.txt文件。 - 执行脚本: 对于
data.txt的每一行,awk都会用解析好的脚本进行处理。 - 输出结果: 将处理结果打印到标准输出。
实践示例
让我们通过一个具体的例子来感受 -f 的威力。
示例场景
假设我们有一个名为 students.txt 的文件,内容如下:

students.txt
Alice 90 85 88
Bob 78 92 80
Charlie 88 76 95
David 95 89 91
我们的目标是:计算每个学生的平均分,并输出姓名和平均分。
步骤 1: 创建 awk 脚本文件
我们不使用命令行,而是创建一个名为 calculate_average.awk 的文件。
calculate_average.awk
# BEGIN 块:在处理任何行之前执行
BEGIN {
# 设置输出字段的分隔符为制表符,使输出更美观
OFS = "\t";
# 打印表头
print "Name", "Average";
}
# 主处理块:对输入文件的每一行都执行
{
# $1 是第一个字段(姓名),$2, $3, $4 是分数
name = $1;
# 计算总分
total = $2 + $3 + $4;
# 计算平均分
# 使用 int() 函数对结果取整
average = int(total / 3);
# 打印结果
print name, average;
}
# END 块:在处理完所有行之后执行
END {
# 可以在这里做一些收尾工作,比如打印总结信息
# print "--- End of Report ---";
}
脚本文件解析:
BEGIN { ... }: 在读取第一行数据之前执行一次,我们用它来设置输出格式和打印表头。- 这是
awk的主循环体,它对students.txt的每一行都执行一次。$1,$2等是当前行的字段。 END { ... }: 在读取完所有数据行之后执行一次,我们用它来做一些收尾工作(虽然这个例子中没用到)。
步骤 2: 使用 -f 选项运行脚本
我们可以在终端中执行以下命令:
awk -f calculate_average.awk students.txt
步骤 3: 查看输出
命令执行后,终端会显示以下结果:
Name Average
Alice 87
Bob 83
Charlie 86
David 91
可以看到,输出清晰、格式规范,并且整个逻辑都封装在 calculate_average.awk 文件中,非常易于管理和修改。
高级用法:指定多个脚本文件
awk -f 选项可以重复使用,以加载多个脚本文件,这些脚本会按照指定的顺序被加载和执行。
awk -f common_functions.awk -f main_logic.awk input.txt
在这种情况下,awk 会先加载 common_functions.awk,然后加载 main_logic.awk,如果两个文件中有同名的变量或函数,后加载的文件会覆盖先加载的。
与 shebang 结合使用
对于非常复杂的脚本,你可以将其变成一个可执行的 shell 脚本,在脚本文件的第一行加上 shebang(#!/usr/bin/awk -f),然后赋予执行权限。
将 calculate_average.awk 改为可执行:
-
修改文件内容并添加 shebang:
calculate_average
#!/usr/bin/awk -f BEGIN { OFS = "\t"; print "Name", "Average"; } { name = $1; total = $2 + $3 + $4; average = int(total / 3); print name, average; } -
赋予执行权限:
chmod +x calculate_average
-
直接运行脚本文件:
./calculate_average students.txt
这种方式使得 awk 脚本看起来像一个独立的、可执行的程序,非常方便。
| 特性 | awk 'script' (命令行) |
awk -f script.awk (文件) |
|---|---|---|
| 适用场景 | 简单、一次性、单行的文本处理。 | 复杂、重复性、多行的文本处理任务。 |
| 可读性 | 差,脚本混杂在命令中。 | 高,脚本有独立的文件和格式。 |
| 可维护性 | 低,修改困难。 | 高,只需编辑脚本文件。 |
| 可重用性 | 低,脚本与命令绑定。 | 高,脚本文件可被多次调用。 |
| 调试 | 困难。 | 容易,可以使用任何文本编辑器。 |
awk -f 是将 awk 从一个简单的命令行工具转变为一个功能强大的脚本语言的关键,对于任何非琐碎的任务,强烈推荐使用 -f 选项来组织你的 awk 代码。
