Awk入门
Completion requirements
编写一个大型 Awk 程序
前面的示例虽然有趣,但它们只是对 coins.txt
文件进行了零散的分析。为什么不让 Awk 一次性 计算所有有趣的信息呢?
如何编写一个完整的 Awk 脚本
直接在命令行输入大量 Awk 语句是不现实的,但这个问题很容易解决——我们可以把 Awk 命令写入一个文件,然后让 Awk 执行这个文件。
执行 Awk 脚本的基本格式如下:
awk -f awk脚本文件名 数据文件名
例如:
awk -f summary.awk coins.txt
这样,我们可以编写更复杂的 Awk 程序,而不受命令行输入长度的限制。
“完整”金币数据分析程序
假设我们想让 Awk 生成如下统计信息:
Summary Data for Coin Collection:
Gold pieces: nn
Weight of gold pieces: nn.nn
Value of gold pieces: nnnn.nn
Silver pieces: nn
Weight of silver pieces: nn.nn
Value of silver pieces: nnnn.nn
Total number of pieces: nn
Value of collection: nnnn.nn
下面是实现该功能的 Awk 脚本:
# 这是一个用于统计金币和银币信息的 Awk 脚本
/gold/ { num_gold++; wt_gold += $2 } # 统计金质硬币数量和重量
/silver/ { num_silver++; wt_silver += $2 } # 统计银质硬币数量和重量
END {
val_gold = 485 * wt_gold; # 计算金币总价值
val_silver = 16 * wt_silver; # 计算银币总价值
total = val_gold + val_silver;
print "Summary data for coin collection:";
printf("\n");
printf(" Gold pieces:\t\t%4i\n", num_gold);
printf(" Weight of gold pieces:\t%7.2f\n", wt_gold);
printf(" Value of gold pieces:\t%7.2f\n", val_gold);
printf("\n");
printf(" Silver pieces:\t\t%4i\n", num_silver);
printf(" Weight of silver pieces:\t%7.2f\n", wt_silver);
printf(" Value of silver pieces:\t%7.2f\n", val_silver);
printf("\n");
printf(" Total number of pieces:\t%4i\n", NR);
printf(" Value of collection:\t%7.2f\n", total);
}
程序解析
1. 注释
在 Awk 中,#
用于注释,#
之后的所有内容都会被忽略。
2. 变量 num_gold
和 num_silver
/gold/ { num_gold++; wt_gold += $2 }
/silver/ { num_silver++; wt_silver += $2 }
num_gold++
统计金质硬币的数量,num_silver++
统计银质硬币的数量。wt_gold += $2
累加金质硬币的总重量,wt_silver += $2
统计银质硬币的总重量。
3. END
代码块
END {
val_gold = 485 * wt_gold;
val_silver = 16 * wt_silver;
total = val_gold + val_silver;
}
- 计算金币价值:假设金价 $485/盎司,所以
val_gold = 485 * wt_gold
。 - 计算银币价值:假设银价 $16/盎司,所以
val_silver = 16 * wt_silver
。 - 计算总价值:
total = val_gold + val_silver
。
4. printf
格式化输出
printf(" Gold pieces:\t\t%4i\n", num_gold);
printf(" Weight of gold pieces:\t%7.2f\n", wt_gold);
%4i
:表示输出整数(num_gold
),占 4 个字符宽度,右对齐。%7.2f
:表示输出浮点数(wt_gold
),共 7 个字符宽度,小数部分保留 2 位。
运行脚本
将上面的 Awk 代码保存到 summary.awk
文件中,然后运行:
awk -f summary.awk coins.txt
运行结果
Summary data for coin collection:
Gold pieces: 9
Weight of gold pieces: 6.10
Value of gold pieces: 2958.50
Silver pieces: 4
Weight of silver pieces: 12.50
Value of silver pieces: 200.00
Total number of pieces: 13
Value of collection: 3158.50
关于 printf
语句
1. printf
语法
printf("<格式化代码>", <参数>)
2. 常见特殊字符
字符 | 功能 |
---|---|
\n |
换行 |
\t |
制表符(对齐) |
3. 常见格式化代码
代码 | 含义 |
---|---|
%i 或 %d |
整数 |
%f |
浮点数 |
%s |
字符串 |
4. 示例
printf("%2d", 7) # 输出: " 7"(宽度为 2,右对齐)
printf("%7.2f", 123.456) # 输出: " 123.46"(保留 2 位小数,总宽度 7)
注意:
printf
不会自动换行,所以需要手动添加\n
。\t
用于创建 对齐格式,默认 每 8 个字符 作为一个对齐点。
练习
- 修改
summary.awk
统计并显示coins.txt
中的不同国家的数量。 - 编写 Awk 脚本,统计空行和非空行的数量(使用
NF
变量)。 - 修改练习 2,计算每行的平均单词数。
在下一章,我们将学习如何编写多行 Awk 代码,以便实现更加复杂的功能。
Last modified: Thursday, 30 January 2025, 12:35 AM