打字猴:1.700436944e+09
1700436944 UNIX传奇:历史与回忆 [:1700434702]
1700436945 UNIX传奇:历史与回忆 5.4 sed和awk
1700436946
1700436947 Unix文件系统的主要简化之一是将文件统统看作为未经解释的字节序列。没有记录,没有必需或禁止的字符,也没有文件系统强加的内部结构,只有字节。
1700436948
1700436949 大多数Unix程序处理文本数据的方式也同等简单。文本文件只是字节序列,恰好是ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)中的字符。统一的纯文本视角天然适合于管道。Unix工具箱中装满了读取文本输入、对其进行处理并输出文本的程序。上文已提到一些例子,如计词、比较、排序、翻译和查找重复内容,当然还有那个典型的例子,用于检索的grep。
1700436950
1700436951 1. sed
1700436952
1700436953
1700436954
1700436955
1700436956
1700436957 grep大获成功,李·麦克马洪受到启发,写了类似程序gres,它可以在文本流过时进行简单替换;“gres”末尾那个“s”代表ed中的替换命令。李很快就写出通用的流编辑器sed,取代了gres。sed在文本从输入到输出的过程中应用一系列编辑命令,grep和gres都是sed的特例。sed使用的命令与标准ed文本编辑器中的编辑命令相同。今天,sed在shell脚本中经常被用于以某种方式转换数据流:替换字符,添加或删除不需要的空格,或丢弃不需要的东西。
1700436958
1700436959 李经历非凡——他是哈佛大学的心理学博士,曾在耶稣会神学院学习,准备成为神职人员,后来却踏上了更世俗化的计算机科学家之路。他是Unix小组中最早思考大规模处理文本的人之一,而当时主存储器还处于小到根本无法存储大量文本的阶段。多说一句,“大量”是相对而言。李在20世纪70年代初对《联邦论:美国宪法述评》(Federalist Papers)特别感兴趣,文集中所有文章加起来总共只有1 MB多一点。
1700436960
1700436961 2. awk
1700436962
1700436963
1700436964
1700436965
1700436966
1700436967 我对能同时处理数字和文本的工具很感兴趣。grep和sed都不能处理数字数据或进行计算,grep也不能处理多行文本,这类运算仍然需要C语言程序。我想找一种通用方案。与此同时,阿尔·阿霍(图5-14)一直在试验支持比grep更丰富的正则表达式类别的方法,并编写了egrep(“扩展grep”,extended grep)。彼得·温伯格对数据库感兴趣,他不久后调入1127中心,搬到我和阿尔之间的办公室。
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
[ 上一页 ]  [ :1.700436944e+09 ]  [ 下一页 ]