您的位置:首页 > 其它

awk 数组 排序

2010-12-06 11:53 549 查看
awk作为一门脚本语言,支持的数据类型主要是简单变量和数组
变量。awk中的数组与传统的C和java中的数组不同,更类似于C++
STL中的map或python中的dict,是关联式数组,通过关联关系将key和value结合起来。并且它并不限制key和value的类型,可以
在一个数组中混合使用多种类型的key和value(尽管可能不常这么用)。awk中的变量在使用之前是不需要声明的,在第一次使用时确定它的类型,并且
以后不再改变。所以如果一个变量arr第一次被当做数组来使用,那么以后就不能在用作简单变量。假定arrary是一个数组变量,如果key不在
array中,那么arrary[key]将返回一个空串;如果key在array中,则返回对应的变量arrary[key]。awk可以通过关键字
in来判断key是否在数组中出现。并且可以通过for(key in array)的形式来遍历数组中的元素。

下面给出一个简单的例子来介绍数组的使用,假定有一个文件,各行都是类似:

uid: 1234 song: YestodayOnceMore spack: 123 ppack: 345 time: 234

现在我们需要统计歌曲为YestodayOnceMore各行中出现的spack和ppack,平均时间time,可以使用以下的脚本:

view plain
copy to clipboard
print
?

BEGIN{

arr["spack"
] = 0;

arr["ppack"
] = 0;

arr["time"
] = 0;

count = 0;

}

/$4 == "YestodayOnceMore"
/{

arr["spack"
] += strtonum($6);

arr["ppack"
] += strtonum($8);

arr["time"
] += strtonum($10);

count += 1

}

END{

for
(v in arr)

{

print v, "="
, arr[v];

}

if
(count > 0)

print "average time = "
, arr[
"time"
]/count;

else

print "average time = 0"
;

}

BEGIN{
arr["spack"] = 0;
arr["ppack"] = 0;
arr["time"]    = 0;
count = 0;
}
/$4 == "YestodayOnceMore"/{
arr["spack"] += strtonum($6);
arr["ppack"] += strtonum($8);
arr["time"] += strtonum($10);
count += 1
}
END{
for(v in arr)
{
print v, "=", arr[v];
}
if(count > 0)
print "average time = ", arr["time"]/count;
else
print "average time = 0";
}


awk中数组的排序问题

awk中的数组是关联式的,因此在使用for(key in
array)的方式进行遍历的时候,输出的顺序并不是按照key进行排序输出的,因为awk中的数组内部采用hash的方式实现,因此输出的顺序能是不确
定的。当需要按照某种顺序输出元素时,需要使用到asort和asorti函数来辅助。

asort的原型为:

asort(array1[, arrary[2]])

asort是将数组的value值进行排序,并且返回数组中元素的个数。如果采用asort(array)这种简略方式,那么重排之后的数据将会保

存在array中,但是关联关系将会被取消,下面是一个简单的例子:

view plain
copy to clipboard
print
?

"wang"
=> 15 1 => 33

"lim"
=> 14 2 => 19

"zhuang"
=> 19 asort() -> 3 => 15

"han"
=> 334 4 => 14

"feng"
=> 11 5 => 11

"wang"	=>  15			1  => 33
"lim"	=>  14			2  => 19
"zhuang"=>  19	asort() ->	3  => 15
"han"	=>  334			4  => 14
"feng"	=>  11			5  => 11


排序结束之后,原先的关联关系被取消,取而代之的是index与value的对应关系。

如果需要对key进行排序,那么可以使用asorti函数,该函数的原型为:

asorti(array1[, array2])

asorti将数组的key值进行排序,并返回数组中元素的个数。与asort类似,如果使用asorti(array)这种简略的方式,那么排序后的key值成为value值,原先的关联关系被破坏。下面是一个简单的例子:

view plain
copy to clipboard
print
?

"wang"
=> 15 1 => feng

"lim"
=> 14 2 => han

"zhuang"
=> 19 asort() -> 3 => lim

"han"
=> 33 4 => wang

"feng"
=> 11 5 => zhuang

"wang"  =>  15                 1  => feng
"lim"	=>  14                 2  => han
"zhuang"=>  19    asort() ->   3  => lim
"han"   =>  33                 4  => wang
"feng"  =>  11                 5  => zhuang


如过想要保留原先的关联关系,则可以使用asorti(array1, array2)这种形式,排序后的key被保存在array2数组中。

假定有如下的问题:有一个文件包含了一组人员的信息,格式的类型为:

view plain
copy to clipboard
print
?

Name Age Height Weight

wanger 18 173 74

liusan 20 177 80

zhaojun 24 167 49

tianjing 30 179 75

haobo 28 171 65

Name	 Age	Height  Weight
wanger 	 18    173     	74
liusan	 20    177     	80
zhaojun  24    167     	49
tianjing 30	179	75
haobo	 28	171	65


我们想要按照其中的某一项(比如身高)进行排序,当然是用sort工具就可以实现,现在我们使用awk来实现。下面是按照身高对所有的条目进行排序的代码:

view plain
copy to clipboard
print
?

{

arrary[$2] = $0

}

END{

asorti(arrary, height);

for
(h in height)

{

print arrary[height[h]];

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: