Awk入门
调用 Awk
使用 Awk 的基本格式如下:
awk -F分隔符 -f 程序文件 变量定义 输入文件
其中,每个参数都是可选的。
字段分隔符(Field Separator)
Awk 默认使用 空格 作为字段分隔符,但可以使用 -F
选项更改它。例如,许多数据文件使用 制表符(Tab) 进行分隔,这样字段内部可以包含空格。另外,常见的分隔符还包括冒号(:
)和分号(;
)。
示例
在 Unix/Linux 系统中,/etc/passwd
文件存储了所有用户的信息,并使用 冒号 :
作为字段分隔符。以下命令提取每个用户的用户名和用户 ID:
awk -F: '{ print $1, $3 }' /etc/passwd
注意:
-F:
指定了:
作为字段分隔符。如果不加-F:
,Awk 会默认按空格分隔字段,该命令将无法正确解析/etc/passwd
文件。
Awk 程序文件
一个 Awk 程序的通用结构如下:
BEGIN { 初始化 }
模式1 { 操作 }
模式2 { 操作 }
...
END { 结束操作 }
如果 Awk 代码较长,可以将其存入文件,并使用 -f
选项执行。例如:
awk -f my_script.awk my_data.txt
对于短小的 Awk 代码,也可以直接在命令行输入:
awk '{print $1, $2}' my_data.txt
注意:
- 在 命令行 上输入 Awk 代码时,推荐使用 单引号
'
以防止 Shell 解释特殊字符。- Windows 的
COMMAND.COM
Shell 不支持单引号,在 Windows 命令提示符下可能需要使用 双引号" "
或 反斜杠转义字符\
。
命令行变量
有时,我们需要在执行 Awk 代码时动态设置变量。例如,在计算金币和银币的总价值时,金银的价格直接写在代码中:
END {
val_gold = 485 * wt_gold
val_silver = 16 * wt_silver
}
如果金银价格变化,我们需要修改代码。更好的做法是将价格作为变量,在命令行传入:
awk -f summary.awk pg=485 ps=16 coins.txt
在 Awk 代码中,修改计算部分:
END {
val_gold = pg * wt_gold
val_silver = ps * wt_silver
}
注意:
- 命令行变量 需要使用
pg=485
而不是pg = 485
,因为pg = 485
可能会引起命令行解析错误。
数据文件
Awk 需要一个输入文件,例如 coins.txt
:
awk -f summary.awk coins.txt
但输入文件 是可选的:
- 如果未指定数据文件,Awk 从标准输入读取数据,可通过
CTRL-D
结束输入。 - 可以同时处理多个数据文件:
这将依次处理awk -f summary.awk file1.txt file2.txt
file1.txt
和file2.txt
,并将它们视为一个连续的数据流。
练习
-
尝试运行
/etc/passwd
解析程序awk -F: '{ print $1, $3 }' /etc/passwd
观察去掉
-F:
后的运行结果。 -
将
coins.txt
转换为制表符分隔的文件awk '{print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5, $6, $7, $8}' coins.txt > tabcoins.txt
运行:
awk -F'\t' -f summary.awk tabcoins.txt
这样可以在字段中包含空格,例如
pure gold
或98% pure silver
,仍然保持正确的格式。 -
使用多个数据文件
awk -f summary.awk coins1.txt coins2.txt
观察 Awk 如何处理多个文件并生成合并后的输出。
-
编写 Awk 计算器
- 让用户输入类似
10 + 5
、20 - 3
,然后输出计算结果。 - 代码示例:
awk '{ if ($2 == "+") print $1 + $3; else if ($2 == "-") print $1 - $3; else if ($2 == "*") print $1 * $3; else if ($2 == "/") print $1 / $3; else print "Invalid operator!" }'
- 运行:
echo "10 + 5" | awk -f calculator.awk echo "20 - 3" | awk -f calculator.awk
- 注意:按
CTRL-D
结束输入。
- 让用户输入类似
下一步
下一章将介绍 Awk 最强大的功能——模式匹配(Pattern Matching),使我们可以基于复杂的条件筛选和处理文本数据。