Awk为数组处理提供关联索引。可以迭代一维数组的元素:
e.g。
for(index in arr1)
print "arr1[" index "]=" arr1[index]
但是这种二维数组怎么做?下面给出了哪种语法?
for(index1 in arr2)
for(index2 in arr2)
arr2[index1,index2]
答案 0 :(得分:35)
AWK通过将索引与SUBSEP变量(0x1c)中保存的字符连接来伪造多维数组。您可以使用split
这样迭代二维数组(基于info gawk
文件中的示例):
awk 'BEGIN { OFS=","; array[1,2]=3; array[2,3]=5; array[3,4]=8;
for (comb in array) {split(comb,sep,SUBSEP);
print sep[1], sep[2], array[sep[1],sep[2]]}}'
输出:
2,3,5
3,4,8
1,2,3
但是,您可以使用嵌套for循环遍历数字索引数组:
for (i = 1; i <= width; i++)
for (j = 1; j < = height; j++)
print array[i, j]
来自GAWK manual的另一个值得注意的信息:
要测试多维数组中是否存在特定索引序列,请使用与单维数组相同的运算符(in)。将整个索引序列写在括号中,用逗号分隔,作为左操作数:
(subscript1, subscript2, ...) in array
答案 1 :(得分:5)
不,语法
for(index1 in arr2) for(index2 in arr2) {
print arr2[index1][index2];
}
不起作用。 Awk并不真正支持多维数组。它做了什么,如果你做了像
这样的事情x[1,2] = 5;
是连接两个索引(1&amp; 2)以生成一个字符串,用SUBSEP
变量的值分隔。如果这等于“*”,那么你将具有与
x["1*2"] = 5;
SUBSEP
的默认值是非打印字符,对应于Ctrl + \。您可以使用以下脚本查看此内容:
BEGIN {
x[1,2]=5;
x[2,4]=7;
for (ix in x) {
print ix;
}
}
运行此命令:
% awk -f scriptfile | cat -v
1^\2
2^\4
因此,在回答您的问题时 - 如何迭代多维数组 - 只需使用一个for(a in b)
循环,但您可能需要一些额外的工作才能将a
拆分为x
1}}和y
部分。
答案 2 :(得分:3)
当前版本的 gawk (gnu awk,默认为 linux,并且可以随处安装),具有真正的多维数组。
for(b in a)
for(c in a[b])
print a[b][c], c , b
另见函数isarray()
答案 3 :(得分:2)
我将提供一个示例,说明如何在处理查询数据的工作中使用它。假设您有一个完整的产品类别和客户ID的提取文件:
customer_id category sales
1111 parts 100.01
1212 parts 5.20
2211 screws 1.33
...etc...
易于使用的awk可以通过购买来计算不同的客户:
awk 'NR>1 {a[$1]++} END {for (i in a) total++; print "customers: " total}' \
datafile.txt
但是,计算每个类别中购买的不同客户的数量表示二维数组:
awk 'NR>1 {a[$2,$1]++}
END {for (i in a) {split(i,arr,SUBSEP); custs[arr[1]]++}
for (k in custs) printf "category: %s customers:%d\n", k, custs[k]}' \
datafile.txt
custs[arr[1]]++
的增量有效,因为每个category / customer_id对都是唯一的,作为awk使用的关联数组的索引。
事实上,我使用的gnu awk更快,可以像D. Williamson所提到的那样array[i][j]
。但我想确保我能用标准的awk做到这一点。
答案 4 :(得分:1)
awk(1)最初设计 - 部分 - 是C语言的教学工具,多维数组几乎都是C和awk(1)。因此POSIX IEEE 1003.2标准化了它们。
要探索语法和语义,如果您创建名为&#34; test.awk&#34;的以下文件:
BEGIN {
KEY["a"]="a";
KEY["b"]="b";
KEY["c"]="c";
MULTI["a"]["test_a"]="date a";
MULTI["b"]["test_b"]="dbte b";
MULTI["c"]["test_c"]="dcte c";
}
END {
for(k in KEY) {
kk="test_" k ;
print MULTI[k][kk]
}
for(q in MULTI) {
print q
}
for(p in MULTI) {
for( pp in MULTI[p] ) {
print MULTI[p][pp]
}
}
}
并使用此命令运行它:
awk -f test.awk /dev/null
您将获得以下输出:
date a
dbte b
dcte c
a
b
c
date a
dbte b
dcte c
至少在Linux Mint 18 Cinnamon 64-bit 4.4.0-21-generic#37-Ubuntu SMP