核心概念
awk 命令 -f 选项的主要作用是:从指定的文件中读取 awk 程序脚本,而不是在命令行中直接编写脚本。

这就像很多命令(如 tar -f)一样,-f 通常用来指定一个文件作为输入源,对于 awk 而言,这个文件里存放的是你想要执行的 awk 代码。
为什么需要 -f 选项?
虽然简单的 awk 脚本可以直接在命令行中书写,但一旦脚本变得复杂(包含多个 BEGIN 和 END 块、多个条件处理、函数定义等),在命令行中输入和维护就会变得非常困难和易错。
使用 -f 选项有以下主要优点:
- 可读性强:将代码放在一个独立的
.awk文件中,结构清晰,易于阅读和理解。 - 可维护性高:当需要修改脚本时,只需编辑对应的
.awk文件,而不需要重新输入一长串命令。 - 可重用性:编写好的
.awk脚本文件可以在不同的数据文件上重复使用。 - 便于调试:可以在
.awk文件中使用print语句等工具进行调试,而不用担心命令行引号转义等问题。
语法格式
使用 -f 选项的基本语法如下:

awk -f script_filename input_file1 input_file2 ...
awk: 命令本身。-f: 告诉awk接下来要从一个文件读取脚本。script_filename: 包含awk脚本的文件路径,这个文件通常以.awk作为扩展名,但这并非强制要求。input_file1 ...: 你想要用该脚本处理的输入数据文件,如果省略输入文件,awk会从标准输入(例如管道)读取数据。
实战示例
假设我们有一个名为 students.txt 的数据文件,内容如下:
students.txt
Alice 90 85 92
Bob 78 88 76
Charlie 95 91 89
David 82 79 85
示例 1:简单的脚本文件
我们想计算每个学生的平均分。
步骤 1:创建 awk 脚本文件

创建一个名为 calculate_average.awk 的文件,内容如下:
calculate_average.awk
{
# $1 是名字, $2, $3, $4 是三科成绩
total = $2 + $3 + $4
average = total / 3
# 使用 printf 进行格式化输出,保留两位小数
printf "%s 的平均分是: %.2f\n", $1, average
}
步骤 2:执行命令
在终端中运行以下命令:
awk -f calculate_average.awk students.txt
输出结果:
Alice 的平均分是: 89.00
Bob 的平均分是: 80.67
Charlie 的平均分是: 91.67
David 的平均分是: 82.00
示例 2:包含 BEGIN 和 END 块的复杂脚本
我们不仅想计算每个学生的平均分,还想在所有数据处理完成后,输出一个班级总分的统计信息。
步骤 1:创建 awk 脚本文件
创建一个名为 class_stats.awk 的文件,内容如下:
class_stats.awk
BEGIN {
# 在处理任何数据行之前执行
printf "--- 班级成绩统计 ---\n"
printf "%-10s %s\n", "姓名", "平均分"
printf "---------------------\n"
class_total = 0
student_count = 0
}
{
# 处理每一行数据
total = $2 + $3 + $4
average = total / 3
# 使用 printf 进行格式化输出
printf "%-10s %.2f\n", $1, average
# 累加班级总分和学生人数
class_total += total
student_count++
}
END {
# 在处理完所有数据行之后执行
printf "---------------------\n"
printf "班级总分: %d\n", class_total
printf "班级平均分: %.2f\n", class_total / (student_count * 3) # 注意这里是总科目数
}
步骤 2:执行命令
awk -f class_stats.awk students.txt
输出结果:
--- 班级成绩统计 ---
姓名 平均分
---------------------
Alice 89.00
Bob 80.67
Charlie 91.67
David 82.00
---------------------
班级总分: 1014
班级平均分: 84.50
高级用法:多个 -f 选项
awk 允许你使用多个 -f 选项来加载多个脚本文件,这些脚本文件会按照指定的顺序被加载和执行,后面的脚本可以覆盖前面脚本中定义的同名变量或函数。
语法:
awk -f script1.awk -f script2.awk input_file
示例:
假设 script1.awk 定义了一个变量 x = 10,而 script2.awk 将 x 重新赋值为 20。
script1.awk
BEGIN {
x = 10
print "在 script1.awk 中,x =", x
}
script2.awk
BEGIN {
x = 20
print "在 script2.awk 中,x =", x
print "x 的值是:", x
}
执行命令:
awk -f script1.awk -f script2.awk /dev/null
(使用 /dev/null 作为输入,因为我们只需要 BEGIN 块的执行)
输出结果:
在 script1.awk 中,x = 10
在 script2.awk 中,x = 20
x 的值是: 20
可以看到,script2.awk 中的 x = 20 覆盖了 script1.awk 中的定义。
| 特性 | 描述 |
|---|---|
| 主要用途 | 从指定文件加载 awk 程序脚本。 |
| 语法 | awk -f script_file input_file... |
| 优点 | 提高脚本的可读性、可维护性和可重用性。 |
| 适用场景 | 当 awk 脚本逻辑复杂,代码行数较多时。 |
| 文件扩展名 | 推荐使用 .awk,但非必需。 |
| 高级用法 | 可以使用多个 -f 选项来组合多个脚本文件。 |
掌握 -f 选项是编写高效、健壮 awk 脚本的关键一步,它标志着你从简单的命令行使用者向脚本开发者的转变。
