数组
数组可以说是awk中最常用到的一种变量类型,所以完全有必要单独使用一个小节来说明。
下标与元素存储
BEGIN{ } { array[1] = "abc"; print("array[1]: "array[1]); array["float"] = 1.334; print("array[\"float\"]: "array["float"]); key = "zhimakaimen"; array[key] = "alibaba"; print("array[key]: "array[key]); print("array[\"zhimakaimen\"]: "array["zhimakaimen"]); array[x] = "x"; array[y] = "y"; print("array[x]: "array[x]); print("array[y]: "array[y]); } END{ }
$echo ""|awk -f chapter_2_3-1.awk
array[1]: abc
array["float"]: 1.334
array[key]: alibaba
array["zhimakaimen"]: alibaba
array[x]: y
array[y]: y
通过例程可以发现,数组的下标可以是任意数据类型、数组存储的值也可以是任意数据类型。
数组遍历
BEGIN{ } { array[100] = 100; array["abc"] = "xyz"; array[3.1415926] = "pai"; array[1] = "min value"; array["x"] = 123; print("通过键值来遍历,无序的:"); for ( key in array ) { print("key: "key", value: "array[key]); } print(""); content = "this is content"; split(content, array, " "); print("有序的遍历方式:"); for( i=1; i< =length(array); ++i ) { print("value: "array[i]); } } END{ }
$echo ""|awk -f chapter_2_3-2.awk
通过键值来遍历,无序的:
key: 3.14159, value: pai
key: 100, value: 100
key: x, value: 123
key: abc, value: xyz
key: 1, value: min value有序的遍历方式:
value: this
value: is
value: content
以上例程展示了2种数组的遍历方式:
- 对于下标复杂的数组:采用遍历key的形式,最终的到的输出结果是跟插入顺序无关的;
- 对于
split()
函数得到的数组:因为下标是从1开始连续的,所以可以按照顺序进行遍历。
数组的删除
BEGIN{ } { array[1] = 100; array[2] = 23; array[3] = 15; if ( 2 in array ) { print("array[2]: "array[2]); } else { print("key not found 1"); } delete array[2]; if ( 2 in array ) { print("array[2]: "array[2]); } else { print("key not found 2"); } split("", array, ":"); print("array size:"length(array)); } END{ }
$echo ""|awk -f chapter_2_3-3.awk
array[2]: 23
key not found 2
array size:0
之所以要删除数组目的在于释放其占用的内存空间,数组元素的删除可以通过delete
来完成,但是却无法直接删除整个数组,一种方式是使用for循环来遍历删除,另一种就是通过split()
来变相的清空。
多维数组
BEGIN{ } { array["三年级","一班","班长"] = "小明"; array["三年级","一班","学习委员"] = "小张"; array["三年级","二班","班长"] = "李雷"; array["三年级","二班","学习委员"] = "韩梅梅"; if( ("三年级","一班","班长") in array ) { print("三年级一班有班长"); } if( ("三年级","二班") in array ) { # 无法判断某一维度的值是否存在 } else { print("没有三年级二班"); } # 无法得到某一维度的数组大小,还意外的引入了下标值为“三年级”的数组成员 print("班级数目:"length(array["三年级"])); # 本质上还是一维数组 print("班级领导人数:"length(array)); for( key in array ) { print("key: "key", value: "array[key]); split(key, ids, SUBSEP); print("年级:"ids[1]); print("班级:"ids[2]); print("职务:"ids[3]); print("姓名:"array[key]); } } END{ }
$echo ""|awk -f chapter_2_3-4.awk 三年级一班有班长
没有三年级二班
班级数目:0
班级领导人数:5
key: 三年级, value:
年级:三年级
班级:
职务:
姓名:
key: 三年级一班班长, value: 小明
年级:三年级
班级:一班
职务:班长
姓名:小明
key: 三年级二班班长, value: 李雷
年级:三年级
班级:二班
职务:班长
姓名:李雷
key: 三年级一班学习委员, value: 小张
年级:三年级
班级:一班
职务:学习委员
姓名:小张
key: 三年级二班学习委员, value: 韩梅梅
年级:三年级
班级:二班
职务:学习委员
姓名:韩梅梅
本质上来说awk的多维数组就是用特殊符号SUBSEP
连接多个下标的一维数组,所以很多功能是无法实现的,例如得到某一维度下数组大小。
需要特别注意的是我们判断“班级数目”的代码行,这里向数组中引入了下标为“三年级”,值为空字符串的一个数组成员,但我们的本意其实只是想判断一下某一维度下数组的大小。
数组排序
BEGIN{ } { array["a"] = 30; array["b"] = 10; array["c"] = 20; print("array: "); for ( key in array ) { print("key: " key ", value: " array[key]); } asort(array, result); print("after asort: "); for ( key in result ) { print("key: " key ", value: " result[key]); } values[20] = "a"; values[10] = "b"; values[30] = "c"; print("values: "); for( key in values ) { print("key: " key ", value: " values[key]); } asorti(values, result); print("after asorti"); for ( key in result ) { print("key: " key ", value: " result[key]); } } END{ }
$echo ""|awk -f chapter_2_3-5.awk
array:
key: a, value: 30
key: b, value: 10
key: c, value: 20
after asort:
key: 1, value: 10
key: 2, value: 20
key: 3, value: 30
values:
key: 10, value: b
key: 20, value: a
key: 30, value: c
after asorti
key: 1, value: 10
key: 2, value: 20
key: 3, value: 30
其中asort()
用于对数组元素的排序,下标会丢掉;asorti()
正好相反,对数组下标排序后存储到值中,原来的值丢掉,原型如下:
asort(s [, d])
asorti(s [, d])
s 用于排序的元素数组
d 结果数组,缺省情况下排序后修改s的值,否则传入d中 返回排序后数组的大小