Awk入门
Completion requirements
Nawk(New Awk)的发展与增强功能
Awk 最早在 1977 年 由 Aho、Weinberger 和 Kernighan 开发,最初是为快速编写 "一行命令"(one-liners) 或 短小的文本处理程序 而设计的。然而,Awk 受到了用户的广泛欢迎,一些人甚至将其作为主要编程工具,用于复杂任务。
最初的作者对 Awk 被用于大规模任务感到惊讶,但最终接受了这一事实,并决定改进 Awk,使其成为更强大的通用编程工具。在 1985 年,他们发布了 新版 Awk(Nawk, "New Awk"),以区别于原始版本。
1. Nawk 的主要增强功能
新版 Nawk 引入了多个重要改进,使其更适用于复杂任务:
1.1 用户自定义函数
- 旧版 Awk 不支持函数,代码复用较困难。
- Nawk 允许用户定义函数,使代码结构更加清晰。
示例:实现 signum
(符号函数)
{ for (field=1; field<=NF; ++field) { print signum($field) } }
function signum(n) {
if (n < 0)
return -1
else if (n == 0)
return 0
else
return 1
}
说明
1.2 getline
读取外部文件或管道
- 旧版 Awk 只能处理命令行指定的输入文件。
- Nawk 允许使用
getline
动态读取文件或管道数据。
用法
getline # 从当前输入流读取一行到 `$0`
getline myvar # 读取一行并存入变量 `myvar`
getline < "file" # 从 `file` 读取一行到 `$0`
getline myvar < "file" # 从 `file` 读取一行存入 `myvar`
"ls -l" | getline # 运行命令 `ls -l` 并读取第一行输出到 `$0`
示例:从文件 data.txt
逐行读取
BEGIN {
while (getline line < "data.txt") {
print "Read:", line
}
}
1.3 关闭文件 close()
close("file")
允许重新读取文件,而不必重新启动 Awk。
close("myfile") # 关闭文件 "myfile",下次可以重新读取
1.4 运行 Shell 命令 system()
Nawk 提供 system("command")
来执行 Shell 命令。例如:
system("rm myfile") # 删除文件 myfile
system("date") # 显示当前日期
1.5 访问命令行参数 ARGC
和 ARGV
ARGC
:命令行参数的个数。ARGV
:数组,存储命令行参数。
示例
awk 'BEGIN { print "Total args:", ARGC; for (i=0; i<ARGC; i++) print i, ARGV[i] }' file1 file2
输出
Total args: 3
0 awk
1 file1
2 file2
1.6 三元运算符 ?:
- 格式
status = (condition == "green") ? "go" : "stop"
- 等价于
if (condition == "green") status = "go" else status = "stop"
1.7 新增数学函数
函数 | 描述 |
---|---|
sin(x) |
正弦,x 为弧度 |
cos(x) |
余弦,x 为弧度 |
atan2(y,x) |
y/x 的反正切,范围 -π 到 π |
rand() |
生成 0 <= number < 1 的随机数 |
srand(seed) |
设置随机数种子 |
1.8 新增字符串函数
函数 | 描述 |
---|---|
match(s, r) |
在 s 中查找正则 r ,返回起始索引或 0 |
sub(r, t, s) |
替换 s 中 第一个 符合 r 的部分为 t |
gsub(r, t, s) |
替换 s 中 所有 符合 r 的部分为 t |
示例
BEGIN {
str = "hello world hello"
sub(/hello/, "hi", str) # 替换第一个 "hello"
print str # 输出 "hi world hello"
gsub(/hello/, "hi", str) # 替换所有 "hello"
print str # 输出 "hi world hi"
}
1.9 多维数组支持
示例:打印矩阵及其转置
BEGIN {
count = 1
for (row = 1; row <= 3; ++row) {
for (col = 1; col <= 5; ++col) {
printf("%4d", count)
matrix[row, col] = count++
}
printf("\n")
}
printf("\nTransposed:\n")
for (col = 1; col <= 5; ++col) {
for (row = 1; row <= 3; ++row) {
printf("%4d", matrix[row, col])
}
printf("\n")
}
}
输出
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
Transposed:
1 6 11
2 7 12
3 8 13
4 9 14
5 10 15
1.10 删除数组元素 delete
delete array[key]
- 示例
BEGIN {
arr["apple"] = 5
arr["banana"] = 3
delete arr["apple"]
print "apple count:", arr["apple"] # 输出空值
}
2. 结论
增强功能 | 描述 |
---|---|
用户自定义函数 | 支持 function name(args) {} |
getline 读取外部文件 |
getline var < "file" |
close() 关闭文件 |
close("file") |
system() 运行 Shell 命令 |
system("ls") |
ARGC /ARGV 访问参数 |
ARGV[i] 获取参数 |
三元运算符 ?: |
status = (cond) ? "yes" : "no" |
新增数学函数 | sin(x) , cos(x) , rand() |
新增字符串函数 | match() , sub() , gsub() |
多维数组 | array[row, col] |
删除数组元素 | delete array[key] |
新版 Nawk 更加强大,适合更复杂的文本处理任务!🚀
Last modified: Thursday, 30 January 2025, 1:36 AM