Awk入门
完成条件
变量类型与初始化(Types and Initialization)
在 Awk 中,既支持用户自定义变量,也有内置变量。变量名必须以字母开头,由字母、数字或下划线(_)组成,并且不能与 Awk 保留字 冲突。此外,变量名不能包含空格。
提示:
- 如果 Awk 程序遇到奇怪的错误,尝试更换变量名,可能是由于使用了保留字导致的。
1. 变量初始化
Awk 不需要声明变量,也无法声明变量。但在复杂程序中,建议在 BEGIN
代码块中显式初始化变量,以提高可读性并避免逻辑错误。例如:
BEGIN {
total = 0
count = 0
}
默认值:
- 未初始化的变量 在数值运算时默认为
0
,在字符串操作时默认为""
(空字符串)。- 依赖默认值可能会引发错误,建议显式初始化。
2. 弱类型(Weak Typing)
Awk 没有数据类型,变量可以存储字符串或数值,并根据操作自动转换:
var = 1776 # 作为数值
var = "1776" # 作为字符串(但在数值计算中仍然有效)
两者在数值计算时等价:
print var + 1
输出:
1777
但是,如果 var
赋值为一个非数字字符串:
var = "somestring"
- 字符串操作正常:
输出:print var " is a string"
somestring is a string
- 数值计算时,Awk 会把它当作 0:
输出:print var + 10
10
错误示例:
var = somestring # 变量 somestring 未定义
- 这会创建一个新变量
somestring
,它的值默认为0
,导致错误。
3. 变量未初始化时的行为
- 比较
var == 0
可以检测变量是否未初始化:if (var == 0) print "var is uninitialized"
- 打印未初始化变量时,不会输出
0
,而是空行:
输出:print something
但是如果先显式赋值:(空行)
输出:something = 0 print something
0
4. 数组与字符串
- Awk 字符串变量 不是 字符数组,但可以使用
substr()
访问字符串中的字符:BEGIN { str = "Hello" print substr(str, 1, 2) # 输出 "He" }
- 数组将在后续章节介绍。
Awk 内置变量
变量 | 说明 |
---|---|
$1, $2, ... |
字段变量(输入行的列) |
$0 |
完整的一行 |
NR |
当前处理的行号(从 1 开始) |
NF |
当前行的字段数 |
FILENAME |
当前文件名 |
FS |
输入字段分隔符(默认是空格) |
RS |
输入记录分隔符(默认是换行符) |
OFS |
输出字段分隔符(默认是空格) |
ORS |
输出记录分隔符(默认是换行符) |
OFMT |
数字格式化(默认 "%.6g" ) |
ARGC |
命令行参数数量 |
ARGV |
命令行参数数组 |
5. 变量修改
字段变量 $1, $2
等是可修改的:
$2 = "NewText"
- 这将修改当前行的第二列,但不会影响输入文件。
- 通过
print $0
,可以打印修改后的行:
示例输入awk '{$2="Modified"; print $0}' input.txt
input.txt
:
输出:A B C X Y Z
A Modified C X Modified Z
6. 变量修改与内置变量
可以修改 FS
、OFS
、RS
以改变 Awk 行、字段的处理方式。
6.1 修改 FS
(字段分隔符)
假设 data.txt
文件内容:
name:age:city
Alice:25:NY
Bob:30:LA
使用 FS=":"
来按 :
作为字段分隔符:
awk 'BEGIN { FS=":" } { print $1, $3 }' data.txt
输出:
name city
Alice NY
Bob LA
6.2 修改 OFS
(输出字段分隔符)
awk 'BEGIN { OFS=" - " } { print $1, $2, $3 }' data.txt
输出:
name - age - city
Alice - 25 - NY
Bob - 30 - LA
6.3 修改 RS
(输入记录分隔符)
默认 RS="\n"
(换行符),如果文件是多行记录,可以改为 RS=""
处理空行分隔的数据:
awk 'BEGIN { RS="" } { print "Record:", $0 }' address_book.txt
6.4 修改 ORS
(输出记录分隔符)
awk 'BEGIN { ORS="\n---\n" } { print $0 }' data.txt
输出:
name:age:city
---
Alice:25:NY
---
Bob:30:LA
---
7. 练习
-
地址簿格式化
- 处理多行记录,每个地址用空行分隔:
awk 'BEGIN { FS="\n"; RS="" } { print $1, $2, $3 }' address_book.txt
- 示例
address_book.txt
:John Doe 123 Main St New York, NY Alice Smith 456 Oak St Los Angeles, CA
- 输出:
John Doe 123 Main St New York, NY Alice Smith 456 Oak St Los Angeles, CA
-
格式化数值列表
- 读取特殊分隔符开头的数字列表,并以该分隔符重新格式化:
awk '{ OFS=$1; print $2, $3, $4, $5, $6 }' numbers.txt
- 示例输入
numbers.txt
:, 10 20 30 40 50 - 1 2 3 4 5
- 输出:
10,20,30,40,50 1-2-3-4-5
结论
- Awk 变量是弱类型的,可以存储字符串或数值。
- 未初始化的变量默认为
0
或""
。 - 可修改内置变量(
FS
,OFS
,RS
,ORS
)来改变输入/输出格式。 - 字段
$1, $2, ...
可修改,但不会影响原始文件。
在下一章,我们将学习 Awk 的强大关联数组(Associative Arrays)! 🚀
最后修改: 2025年01月30日 星期四 01:11