awk中的’数组
‘是一种关联数组,又称作maps
、字典
,他的索引不需要连续, 可以使用字符串、数字做为索引, 此外,不需要事先声明数组的大小 – 数组可以在运行时扩展/收缩。
语法:
- 赋值:
array_name[index] = value
- 删除:
delete array_name[index]
- 多维数组(使用字符串模拟)
array["0,0"] = 100
- 遍历:
for (var in arrayname)
actions
实例
统计汇总
数据:Iplogs.txt
180607 093423 123.12.23.122 133
180607 121234 125.25.45.221 153
190607 084849 202.178.23.4 44
190607 084859 164.78.22.64 12
200607 012312 202.188.3.2 13
210607 084849 202.178.23.4 34
210607 121435 202.178.23.4 32
210607 132423 202.188.3.2 167
total.awk:
{
Ip[$3]++;
}
END {
for (var in Ip)
print var, "access", Ip[var]," times"
}
注意下END后的
{
需要和END
在一行
输出:
$ awk -f total.awk Iplogs.txt
123.12.23.122 access 1 times
164.78.22.64 access 1 times
202.188.3.2 access 2 times
125.25.45.221 access 1 times
202.178.23.4 access 3 times
说明:
$3
是一个IP地址, Ip做为数组的索引。
对于每一行,它会增加相应IP地址索引的值。
最后在END部分中,所有索引都将是唯一IP地址的列表,其对应的值是出现次数。
分组统计
数据:first.log.txt
0 child
0 parent
1 child
1 parent
2 parent
2 child
3 parent
3 child
4 parent
4 child
5 parent
5 child
6 parent
6 child
7 parent
7 child
8 parent
8 child
9 parent
9 child
The Linux Programming Interface中的例子:
fork_whos_on_first.count.awk
#!/usr/bin/awk -f
#
# fork_whos_on_first.count.awk
#
# Copyright, Michael Kerrisk, 2002
#
# Read (on stdin) the results of running the fork_whos_on_first.c
# program to assess the percentage iof cases in which parent or child
# was first to print a post-fork() message
#
BEGIN {
last = -1;
}
{
# match pairs of lines by field 1 (loop counter)
if ($1 != last) {
cat[$2]++;
tot++;
}
last = $1;
}
# Our input file may be long - periodically print a progress
# message with statistics so far
NR % 200000 == 0 {
print "Num children = ", NR / 2;
for (k in cat)
printf "%-6s %6d %6.2f%%\n", k, cat[k], cat[k] / tot * 100;
}
END {
print "All done";
for (k in cat)
printf "%-6s %6d %6.2f%%\n", k, cat[k], cat[k] / tot * 100;
}
输出:
$ awk -f fork_whos_on_first.count.awk first.log.txt
All done
parent 8 80.00%
child 2 20.00%
说明:
应用程序输出文本中通过$1
进行分组,使用last
存放上一个$1
的值
通过if ($1 != last)
判断是否是本组第一个出现的记录
$2
是child或parent, 做为数组的索引。
对于每一组,它会增加相应IP地址索引的值。
NR记录行数,每200000输出一次.
最后在END部分中,可以通过数组显示child,parent键值,其对应的值是出现次数。
反转
reverse.awk:
{
a[i++] = $0
}
END {
for (j=i-1; j>=0;)
print a[j--]
}
输出:
$ awk -f reverse.awk Iplogs.txt
210607 132423 202.188.3.2 167
210607 121435 202.178.23.4 32
210607 084849 202.178.23.4 34
200607 012312 202.188.3.2 13
190607 084859 164.78.22.64 12
190607 084849 202.178.23.4 44
180607 121234 125.25.45.221 153
180607 093423 123.12.23.122 133
说明:
它首先记录数组’a’中的所有行。
END块循环遍历数组’a’中的元素,并以反序打印。
也可以使用一下方法:
BEGIN{s=""} {s=$0"\n"s;} END{printf("%s",s);}
去重
数据:data.txt
foo
bar
foo
baz
bar
removedup.awk
!($0 in a) { a[$0]; print }
输出:
$ awk -f removedup.awk data.txt
foo
bar
baz
说明:
$0
表示整行, awk从文件data.txt读取每一行,并使用“in”运算符检查当前行是否存在于数组a
中。
如果它不存在,则存储并打印当前行。
选择最大值
max.awk:
{
date[$1]++;
}
END{
for (count in date)
{
if ( max < date[count] ) {
max = date[count];
maxdate = count;
}
}
print "Maximum access is on", maxdate;
}
输出:
$awk -f max.awk Iplogs.txt
Maximum access is on 210607
说明:
定义变量max,遍历数组获取最大值
多维数组矩阵反转
数据:vector.data
1 2 3 4 5 6
2 3 4 5 6 1
3 4 5 6 1 2
4 5 6 1 2 3
rotate.awk :
{ if (max_nf < NF)
max_nf = NF
max_nr = NR
for (x = 1; x <= NF; x++)
vector[x, NR] = $x
}
END {
for (x = 1; x <= max_nf; x++) {
for (y = max_nr; y >= 1; --y)
printf ("%s ", vector[x, y])
printf ("\n")
}
}
输出:
$ awk -f rotate.awk vector.data
4 3 2 1
5 4 3 2
6 5 4 3
1 6 5 4
2 1 6 5
3 2 1 6
参考&引用
Arrays in awk
AWK Arrays Explained with 5 Practical Examples
Be First to Comment