内容:
陈二 数学 化学 物理
张三 语文 数学 历史
李四 数学 体育 音乐
王五 地理 语文 政治
统计各个科目的报名人数:
数学3
政治1
语文2
物理1
地理1
音乐1
历史1
化学1
体育1
$ awk '{for(i=2;i<=NF;i++)num[$i]++}END{for(x in num) printf('%8s =n',x,num[x])}'file
说明:
这程序包含二个Pattern{Actions}指令.
{for(i=2;i<=NF;i++) num[$i]++}
END{for(x in num) printf("%8s =n",x,num[x])}
第一个Pattern{Actions}指令中省略了Pattern部分.故随着每笔数据行的读入其Actions部分将逐次无条件被执行.
以awk读入第一笔资料"陈二 数学 化学 物理" 为例, 因为该笔数据NF=4(有4个字段),故该Action的for循环中i=2,3,4.
i=2时 $i=数学 num[数学]的值从默认的0,变成了1;(在awk中数组可以用字符串,而并非一定是整数。)
i=3时 $i=化学 num[化学]的值从默认的0,变成了1;
同理,i=4时 $i="物理" Number[物理]的值从默认的0,变成了1;
以次类推,awk又开始匹配第2行"张三 语文 数学 历史";
i=2时 $i=语文 num[语文]的值从默认的0,变成了1;
i=3时 $i=化学 num[化学]的值从1,变成了2;
... ......
以此类推,awk逐行匹配完数据后,最后执行END;
第二个 Pattern{Actions}指令中END为awk之保留字, 为Pattern的一种.
END 成立(其值为true)的条件是: "awk处理完所有数据, 即将离开程序时";
平常读入数据行时, END并不成立,故其后的Actions并不被执行;
唯有当awk读完所有数据时,该Actions才会被执行(注意,不管数据行有多少笔,END仅在最后才成立,故该Actions仅被执行一次.)
BEGIN 与 END 有点类似, 是awk中另一个保留的Pattern.
唯一不同的是: "以 BEGIN为Pattern的Actions于程序一开始执行时,被执行一次."
for(x in num){....}
指定用x来记录awk从num[ ]中所找到的下标,awk每找到一个下标时,就用x记录该下标的值并且执行{....}中之指令,藉由这个方式便可取出数组中储存的数据。