当您学习一门新的编程语言时,最好关注大多数编程语言的共同点:变量——存储信息的地方表达式——方法语句用于计算-在程序中表达状态变化的方法这些概念是大多数编程语言的基础。一旦你理解了这些概念,你就可以开始弄清楚其余的了。例如,大多数语言都有其设计支持的“做事方式”,而这些方式因语言而异。这些方法包括模块化(将相关功能组合在一起)、声明式与命令式、面向对象、低级语法特性与高级语法特性等。很多程序员比较熟悉的是编程“仪式”,即在解决问题之前需要做的场景设置工作。据说Java编程语言在其设计中有一个重要的仪式要求,即所有代码都定义在一个类中。但从根本上说,编程语言往往有相似之处。一旦掌握了一种编程语言,就可以从学习另一种语言的基础知识开始,品尝这门新语言的不同之处。一个好的方法是创建一组基本的测试程序。有了这些,就该开始从相似之处中学习了。您可能选择创建的一个测试程序是“猜数字”程序。计算机从1到100中选择一个数字,并要求您猜这个数字。程序循环直到你猜对为止。“猜数字”程序练习了编程语言中的几个概念:可变输入输出条件判断循环这是学习一门新的编程语言的很好的实践实验。注意:本文改编自MosheZadka在Julia中使用这种方法和JimHall在Bash中使用这种方法。在Awk程序中猜数字让我们编写一个实现“猜数字”游戏的Awk程序。Awk是动态类型的,是一种面向数据转换的脚本语言,对交互使用的支持出奇的好。Awk作为Unix操作系统的一部分出现在1970年代。如果您不了解Awk,但喜欢电子表格,这表明您可以学习Awk!您可以通过编写一个版本的“猜数字”游戏来开始您对Awk的探索。这是我的实现(带有行号,因此我们可以查看一些特定功能):BEGIN{srand(42)randomNumber=int(rand()*100)+1print"randomnumberis",randomNumberprintf"guessanumberbetween1and100\n"}{guess=int($0)if(guessrandomNumber){printf"太高,再试一次:"}else{printf"that'sright\n"exit}}我们可以立即看出Awk的控制结构类似于C或Java,而不是Python。在像if-then-else、while、then、else和while部分接受一个语句或一组由{和}}包围的语句但是,Awk有一个大需要从一开始就了解的区别:按照设计,Awk是围绕数据管道构建的。这是什么意思?大多数Awk程序都是代码片段,接受一行输入,对数据进行一些处理,然后将其写入输出。认识到对此类转换管道的需求,Awk默认提供所有转换管道。让我们通过询问有关上述程序的一个基本问题来进行探索:“从控制台读取数据”的结构在哪里?答案是——“内置”。特别是,第7-17行告诉Awk如何处理它读取的每一行。在本例中,很容易看出第1-6行在读取任何内容之前执行。更具体地说,第1行的BEGIN关键字是一种“模式”,在本例中指示Awk在读取任何数据之前执行{...}BEGIN之后的内容。另一个类似的关键字END在此程序中未使用,它指示Awk在读取所有内容后做什么。回到第7-17行,我们看到他们创建了一个类似于代码块{...}的片段,但前面没有关键字。由于Awk在{之前没有任何东西可以匹配,它会为它接收到的每一行输入使用这一行。每行的输入将由用户作为猜测输入。让我们看看实际的代码。首先,是在读取任何输入之前发生的序言。在第2行,我们用数字42初始化随机数生成器(如果没有提供参数,则使用系统时钟)。为什么使用42?当然选择42!第3行计算1到100之间的随机数,第4行输出该随机数以用于调试目的。第5行邀请用户猜测一个数字。请注意,此行使用printf,而不是print。与C语言一样,printf的第一个参数是用于格式化输出的模板。现在用户知道程序需要输入,她可以在控制台输入一个猜测。如前所述,Awk将此猜测输入到第7-17行的代码中。第18行将输入记录转换为整数;$0表示整个输入记录,而$1表示输入记录的第一个字段,$2表示第二个字段,依此类推。是的,Awk使用预定义的分隔符(默认为空格)将输入行拆分为组成字段。第9-15行将猜测值与随机数进行比较,打印出适当的响应。如果猜测正确,第15行会提前从输入行处理流水线中退出。就这么简单!考虑到Awk程序的不寻常结构,其中片段对特定的输入行配置和处理数据作出反应,让我们看看另一个结构,看看过滤部分是如何工作的:BEGIN{srand(42)randomNumber=int(rand()*100)+1print"randomnumberis",randomNumberprintf"guessanumberbetween1and100\n"}int($0)randomNumber{printf"太高,再试一次:"}int($0)==randomNumber{printf"that'sright\n"exit}第1-6行没有变化。但是现在我们看到7-9行是输入整数值小于随机数时执行的代码,10-12行是输入整数值大于随机数时执行的代码,13-16行等于代码执行时。这看起来“很酷但很奇怪”——例如,为什么我们要双重计算int($0)?可以肯定的是,以这种方式处理问题会很奇怪。但这些模式确实是分离条件处理的一种非常好的方式,因为它们可以使用正则表达式或Awk支持的任何其他结构。为了完整起见,我们可以使用这些模式将通用计算与仅适用于特定环境的计算分开。这是第三个版本:认识到无论输入什么值,都需要将其转换为整数,因此我们创建第7-9行来执行此操作。现在10-12、13-15、16-19行都是引用已经定义好的变量guess,而不是每次都转换输入行。让我们回到我们想要学习的东西列表:变量——是的,Awk有这些;我们可以推断输入数据以字符串形式出现,但可以在需要时转换为数字输入-Awk只是通过“数据转换管道”方式发送输入以读取数据输出-我们使用了Awk的print和printf函数来写内容输出条件判断——我们学习了AwkIf-then-else和为特定输入行配置的输入过滤器循环——好吧,想象一下!多亏了Awk采用的“数据转换管道”方法,我们在这里不需要循环;循环“恰好发生”。请注意,用户可以通过向Awk发送文件结束信号(使用Linux终端窗口时的快捷方式CTRL-D)来提前退出管道。不需要循环来处理输入的重要性是非常值得的。Awk存活了这么久的原因之一是Awk程序是紧凑的,而它们之所以紧凑的原因之一是它们不需要那些从控制台或文件中读取的格式化代码。让我们运行下面的程序:我们没有涉及的一件事是注释。awk注释以#开始,以行尾结束。总结Awk非常强大,这个“猜数字”游戏是一个很好的入门方式。但这不应该是您探索Awk的终点。你可以看看Awk和Gawk(GNUAwk)的历史,Gawk是Awk的扩展版本,如果你的电脑上运行Linux,你可能有这个。或者,从原始开发者处阅读有关原始版本的各种信息。您还可以下载我们的备忘单,以帮助您跟踪所学的一切。Awk备忘单