原文:http://doc.lazyhack.net/awk.htm 

awk 中数组

awk程序中允许使用字符串当做数组的下标(index). 利用这个特色十分有助于资料统计工作.(使用字符串当下标的数组称为Associative Array)

首先建立一个数据文件并取名为 reg.dat. 此为一学生注册的资料文件第一栏为学生姓名其后为该生所修课程.

Mary O.S. Arch. Discrete

Steve D.S. Algorithm Arch.

Wang Discrete Graphics O.S.

Lisa Graphics A.I.

Lily Discrete Algorithm

awk中数组的特性

1、使用字符串当数组的下标(index).

2、使用数组前不须声明数组名及其大小.

例如希望用数组来记录 reg.dat 中各门课程的修课人数.

这情况,有二项信息必须储存:

(a) 课程名称: "O.S.","Arch.".. ,共有哪些课程事先并不明确.

(b)各课程的修课人数有几个人修"O.S."

awk中只要用一个数组就可同时记录上列信息其方法如下:

使用一个数组 Number[ ] :

以课程名称当 Number[ ] 的下标.

 Number[ ] 中不同下标所对映的元素代表修课人数.

例如:2个学生修 "O.S.", 则以 Number["O.S."] = 2 表之.

如何取出数组中储存的信息

awk 提供了一个指令由该指令awk会自动找寻数组中使用过的所有下标 Number[ ] 为例, awk将会找到 "O.S.", "Arch.",...

使用该指令时须指定所要找寻的数组及一个变量. awk会使用该的变量来记录从数组中找到的每一个下标例如

for(course in Number){....}

指定用 course 来记录 awk Number[ ] 中所找到的下标. awk每找到一个下标时就用course记录该下标之值且执行{....}中之指令藉由这个方式便可取出数组中储存的信息.

例子:

统计各科修课人数,并印出结果.

awk '{for (i=2;i<=NF;i++)a[$i]+=1}END{for (i in a)printf ("%10s %d\n",i,a[i])}' reg.dat

输出结果

Graphics 2

      O.S. 2

  Discrete 3

      A.I. 1

      D.S. 1

     Arch. 2

 Algorithm 2

说明:程序包含两个pattern{actions}

{ for( i=2; i <= NF; i++) Number[$i]++ }:省略了pattern故无条件的对所有行执行后面actions

awk读入第一行 " Mary O.S. Arch. Discrete"为例,NF=4,所以for loop中的i=2,3,4

i=2时,$i=$2= "O.S."  Number[$i]=Number[$2]= Number["O.S."] 由默认值0变成1

i=3时,$i=$3= "Arch."  Number[$i]=Number[$3]=Number["Arch."] 由默认值0变成1

i=4同理

END{for(course in Number) printf("%10s %d\n", course, Number[course] )}

该指令中ENDawk的保留字,为pattern的一种其成立(值为true)的条件是:“awk处理完所有的数据,即将离开程序时。”

当读入行的时候END不成立,故不执行后面的actions,当awk读完所有的数据时,改actions会被执行,且只被执行一次。

BEGINEND类似,相反以BEGINpatternactions只会在awk读取数据前执行一次

 

注意:以 i= 2 为例, $i = $2 表第二个字段数据. ( 实际上, $  awk 中为一运算符(Operator), 用以取得字段数据.)