数组
数组可以说是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中 返回排序后数组的大小