打字猴:1.700436968e+09
1700436968
1700436969
1700436970
1700436971
1700436972 图5-14 阿尔·阿霍,约1981年(杰勒德·霍尔兹曼供图)
1700436973
1700436974 1977年秋天,我们3个人讨论如何将这些想法结合起来。我们从IBM强大但难以捉摸的报表程序生成器RPG中获得了一些灵感,同时还从马克·罗奇金德(Marc Rochkind)那里得到了一个精妙的点子,在下一章中我会介绍这个点子。最终我们设计出一种语言,起名为AWK(下文写作awk)。正如我们在最初的说明中提到的那样,用作者的名字来命名一门语言是想象力贫乏所致。我不记得我们是否考虑过与awkward[11]相关的同义词,也可能是我们觉得这个名字既风趣又贴切,总之它最后成了程序名。彼得利用Yacc、Lex和阿尔的egrep正则表达式代码,只用了几天时间就写出第一个版本。
1700436975
1700436976 awk程序是模式和动作的序列。每行输入都要测试所有模式,如果模式匹配,则执行相应动作。模式可以是正则表达式,也可以是数字或者字符串关系。不指定模式就会匹配所有行,不指定动作则会输出匹配行。
1700436977
1700436978 下例输出所有长于80个字符的输入行,该模式没有指定动作。
1700436979
1700436980     awk ‘length > 80’
1700436981
1700436982
1700436983
1700436984
1700436985
1700436986 awk支持数字或字符串变量,以及下标为数字或任意字符串的关联数组。变量初始化为零和空字符串,所以通常不需要设置初始值。
1700436987
1700436988 awk自动读取输入文件的每一行,并将其分割成字段,所以很少需要另写代码来读取输入或解析各行。awk还有一些内置变量,包含了当前输入行的编号和该行对应的字段数,所以这些值也不需要另行计算。这些默认值消除了重复代码,意味着许多awk程序只有一两行长。
1700436989
1700436990 例如,下例在每一行开始处加上行号:
1700436991
1700436992     awk ‘{print NR, $0}’
1700436993
1700436994
1700436995
1700436996
1700436997
1700436998 NR是当前输入行的行号,$0是输入行的内容。
1700436999
1700437000 下例统计每个单词的出现次数,并在最后输出单词及其计数。
1700437001
1700437002     { for (i = 1; i <= NF; i++) wd[$i]++ } END { for (w in wd) print w, wd[w] }
1700437003
1700437004
1700437005
1700437006
1700437007
1700437008 程序第一行是没有指定模式的动作,所以对每一行输入内容都有效。内置变量NF是当前输入行的字段数,它是自动计算出来的。变量 $i代表第i个字段,同样是自动计算出来的。语句wd[$i]++使用该值,也就是输入的一个词,作为数组wd的下标,并递增数组中的该元素。读取完最后一行输入后,使用特殊模式END做匹配。注意程序中有两种不同的for循环。第一种直接借用自C语言;第二种是在数组的元素上循环,在本例中,它输出多行文本,每行列出原始输入的每个单词以及该词出现的次数。
1700437009
1700437010 虽然Perl和稍后的Python接管了许多潜在应用场景,但awk今天仍然被广泛使用。它是一个核心工具,至少有四五种独立实现,包括阿诺德·罗宾斯的Gawk和迈克尔·布伦南(Michael Brennan)的Mawk。awk当然存在一些有问题的设计和未尽之处,但我认为它是最能善用语言编程能力的工具——用户花5~10分钟就能大体学会,而且程序代码往往只有几行。它并不适合写大型程序,但这并没有妨碍有人写出长达数千行的awk程序。
1700437011
1700437012 作为被高频使用的shell管道组件,sed广受欢迎。我甚至有一张保险杠贴纸,印着
1700437013
1700437014 “Sed and awk: together we can change everything.”[12]
1700437015
1700437016 值得注意的是,sed、awk、Make、Yacc和Lex都实现了某种程度的模式-动作范式。这些语言中的程序由一系列的模式和动作组成:基本操作是根据每个模式检查输入,当模式匹配时,执行相应的动作。模式和动作有时可能会被省略,在这种情况下,会执行默认行为。
1700437017
[ 上一页 ]  [ :1.700436968e+09 ]  [ 下一页 ]