在awk系列的第八部分,我们介绍了一些强大的awk命令特性,它们是变量、数值表达式和赋值运算符。在本节中,我们将了解更多awk特性,即awk特殊模式:BEGIN和END。随着我们展开并发现更多构建复杂awk操作的方法,它将证明awk的这些特殊功能有多么强大。在开始之前,让我们先回顾一下awk系列的介绍。记得当我们开始这个系列时,我指出awk命令的一般语法是这样的:#awk'script'filenames在上面的语法中,awk脚本的形式为:/pattern/{actions}您通常会发现脚本中的模式(/pattern/)是一个正则表达式。此外,您还可以在此处使用特殊模式BEGIN和END。因此,我们也可以编写如下形式的awk命令:awk'BEGIN{actions}/pattern/{actions}/pattern/{actions}………….END{actions}'filenames如果你在awk脚本中使用特殊模式:BEGIN和END,以下是它们对应的含义:BEGIN模式:表示awk将在读取任何输入行之前立即执行BEGIN中指定的动作。END模式:表示awk在正式退出前会执行END中指定的动作。具有这些特殊模式的awk命令脚本的执行流程如下:在脚本中使用BEGIN模式时,在读取任何输入行之前执行BEGIN中的所有操作。然后,读取输入行并将其解析为不同的段。接下来,每个指定的非特殊模式将与输入行进行比较和匹配,当匹配成功时,将执行该模式对应的动作。对您指定的所有模式重复此步骤。接下来,对所有输入行重复步骤2和3。当所有的输入行都被读取和处理后,如果你指定了END模式,就会执行相应的动作。如果你想在使用特殊模式时在awk操作中获得最好的结果,你应该记住上面的执行顺序。为了便于理解,让我们使用第8节中的示例,它是关于Tecmint拥有的域名列表,并存储在一个名为domains.txt的文件中。news.tecmint.comtecmint.comlinuxsay.comwindows.tecmint.comtecmint.comnews.tecmint.comtecmint.comlinuxsay.comtecmint.comnews.tecmint.comtecmint.comlinuxsay.comwindows.tecmint.comtecmint.com$cat~/domains.txt中查看文件内容在本例中,我们要计算域名tecmint.com在domains.txt文件中的出现次数。于是,我们写了一个简单的shell脚本来帮助我们完成任务,其中使用了变量、数学表达式和赋值运算符的思想,脚本内容如下:#!/bin/bashforfilein$@;doif[-f$file];then###Outputfilenameecho"Fileis:$file"###Outputanincrementalnumberrecordcontainingthelinenumberoftecmint.comawk'/^tecmint.com/{counter+=1;printf"%s\n",counter;}'$fileelse###如果输入不是文件,输出错误信息echo"$fileisnotafile,pleasespecifyafile.">&2&&exit1fidone###在成功执行exit0后以退出代码0终止脚本现在让我们在上述脚本的awk命令中应用这两种特殊模式,如下所示:BEGIN和END:我们应该将脚本:awk'/^tecmint.com/{counter+=1;printf"%s\n",counter;}'$文件改为:awk'BEGIN{print"文件中tecmint.com的出现次数为:";}/^tecmint.com/{counter+=1;}END{printf"%s\n",counter;}'$file修改awk命令后,完整的shell脚本现在如下所示:#!/bin/bashforfilein$@;doif[-f$file];then###输出文件名echo"Fileis:$file"###输出tecmint.com在文件中出现的总次数awk'BEGIN{print"tecmint.com出现的次数。com在文件中出现的是:";}/^tecmint.com/{counter+=1;}END{printf"%s\n",counter;}'$fileelse###如果输入的不是文件,那么输出错误信息echo"$fileisnotafile,Pleasespecifyafile.">&2&&exit1fidone###exit0awkmodeBEGINandEND成功执行后终止脚本,退出代码为0当我们运行上面的脚本时,会先输出domains.txt文件的位置,然后执行awk命令脚本,特殊模式BEGIN中的命令脚本将帮助我们在从文件中读取任何行之前输出类似“Tecmint.comoccursinthefile:”的消息。接下来,我们的模式/^tecmint.com/将出现在每个输入行上比较,匹配成功的每一行都会执行对应的action{counter+=1;},统计tecmint.com在文件中出现的次数。最后,END模式将输出域名tecmint.com在文件中出现的总次数。$./script.sh~/domains.txt用于计算字符串出现次数的脚本***总而言之,在本节中,我们演示了更多awk功能并学习了特殊模式BEGIN和END的概念。正如我之前所说,这些awk函数将帮助我们构建更复杂的文本过滤操作。第十节会给出更多的awk函数,我们会学习awk内置变量的思想,请继续关注。
