且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

awk中的数组

更新时间:2022-08-16 12:37:59

awk中的数组,原文参见[1]

因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格 里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。

1

/> awk 'BEGIN {for(i = 0; i < ARGC; i++) printf("argv[%d] is %s.\n",i,ARGV[i]); printf("The number of arguments, ARGC=%d\n",ARGC)}' testfile "Peter Pan" 12

argv[0] is awk.

argv[1] is testfile.

argv[2] is Peter Pan.

argv[3] is 12.

The number of arguments, ARGC=4

从输出结果可以看出,命令行参数数组ARGV是以0作为起始下标的,命令行的第一个参数为命令本身(awk),这个使用方式和C语句main函数完全一致。

2

/> awk 'BEGIN{name=ARGV[2]; print "ARGV[2] is " ARGV[2]}; $1 ~ name{print $0}' testfile2 "bob"   

ARGV[2] is bob

bob

awk: (FILENAME=testfile2 FNR=9) fatal: cannot open file `bob' for reading (No such file or directory)

先解释一下以上命令的含义,name变量被赋值为命令行的第三个参数,即bob,之后再在输入文件中找到匹配该变量值的记录,并打印出该记录。

在输出的第二行报出了awk的处理错误信息,这主要是因为awkbob视为输入文件来处理了,然而事实上这个文件并不存在,下面我们需要做进一步的处理来修正这个问题。

3

/> awk 'BEGIN{name=ARGV[2]; print "ARGV[2] is " ARGV[2]; delete ARGV[2]}; $1 ~ name{print $0}' testfile2 "bob"   

ARGV[2] is bob

bob

从输出结果中我们可以看到我们得到了我们想要的结果。需要注意的是delete函数的调用必要要在BEGIN模块中完成,因为这时awk还没有开始读取命令行参数中指定的文件。

4

awk中还提供了一种special for的循环,见如下声明:

for (item in arrayname)

{

print arrayname[item]

}

/> awk '{count[$1]++}; END{for(name in count) printf "%-5s%d\n",name, count[name]}' testfile2

mary 4

tom 2

alex 1

bob 1

sean 1

5

/> awk '{count[$1]++}; END{for(name in count) {if (count[name] == 1) delete count[name];} for (name in count) print name}' testfile2

上例中的主要技巧来自END模块,先是变量count数组,如果数组中某个元素的值等于1,则删除该元素,这样等同于删除只出现一次的名字。最后用special for循环打印出数组中仍然存在的元素下标名称。

原文:

http://www.cnblogs.com/mchina/archive/2012/06/30/2571317.html