awk意思:Aho,Weinberger&Kernighan解释语言,这两个人共同发明的。它不是工具,“它是一种伟大的语言,名字很奇怪”。发音:awk[?k]基本用法awk'{print}'/etc/passwd#相当于"cat/etc/passwd"awk'{print$0}'/etc/passwd#相当于花括号中的前一行打印函数用于逐行打印每个匹配的行。print和print$0相当于MultipleFieldsawk-F":"'{print"username:"$1"\t\tuid:"$3}'/etc/passwd#打印第一列和第三列字符串,用制表符分隔awk-F":"'\BEGIN{\print"用户名\tuid"\};{\print$1"\t"$3\}'/etc/passwd#同上,只是把username和uid放在header里打印,看起来更漂亮-F参数表示用":"作为分隔符BEGIN意味着它会在匹配第一行之前执行,所以它非常适合打印HeaderBlock(pattern-action,man-page)可以看到,AWK单引号里面的脚本叫做“AWKScript”,script由一对或多对花括号组成,每个花括号称为Block。像“基本用法”中的单个块是最简单的块。AWK逐行处理文本。每获取一行字符串,就会依次匹配AWKScript中的Blocks,匹配成功后执行Block中的代码。awk'\BEGIN{\FS=":";\计数=0;\打印“用户名\tuid”;\}\{\计数+=1;\print$1"\t"$3\}\END{\print"Totals:"count\}'/etc/passwdawk-fblock.awk/etc/passwd#如果你觉得在命令行输入很麻烦,你也可以将脚本作为文件执行。上面的代码一共有三个block,awk每次拿到一行字符串的时候,会从前到后匹配这三个block,如果匹配了,就执行里面的代码。BEGIN中定义了分隔符FS(FieldSeperator),完全等同于前面“MultipleFields”中的-F选项。另外定义了一个变量count来记录行数。第二个Block没有定义任何条件,所以第一行到最后一行都会匹配成功!END行输出末尾的行数。awk会在要匹配的文本的第一行之前和最后一行之后插入一个空行,只有分别匹配到这两个空行时才会执行BEGIN和ENDBlock。BEGIN和END就像是语法糖,只是执行时间是最前面和最后,其他和普通块没什么区别。由于BEGIN的特性,可以初始化变量定义、打印表头等,工作就在这里;END适用于一些汇总操作,比如打印行数、总字符数、平均行长等。Blockawkwithconditions'\BEGIN{x=0}\/^$/{x=x+1}\END{print"Ifound"x"blanklines.:)"}'file以上代码用于打印file全部为空行,如果你是JSer或者Perl-er,你可能对/^$/很熟悉,参考关系链:JavaScript<-Perl<-awk。awk可以说是这个正则表达式的鼻祖。事实上,在每个Block之前都有一个隐含的条件,一个无条件的Block会匹配文件中所有存在的行(不包括awk插入的两个空行)。当一个块被有条件地附加时,它只会在条件为真时执行。awk'($1==/[0-9]+\.[0-9]*/)&&NR%3{print}'上面的文件只打印以浮点数开头的行,行数不是3的倍数,因为AWKScript是弱类型的,所以像0这样的东西将被评估为false。在awk中,Record是行,所以NR表示记录数。在AWKScript中,所有变量的类型都是字符串。当对字符串进行算术运算(如加减乘除)时,awk会将字符串解析为数字。如果不是合法的数字,则视为0;然后进行算术运算。为了更好的表达BEGIN的意思,欣赏下面的代码:awk'!/^$/&&NR<=100{\if(NR==1){\FS=":";\}\#过滤掉注释和NF小于3的行\if(!($1~/^#/)||NF>=3){\print$1":"$3;\}\}'/etc/passwd整个代码只有一个Block,这个Block只能在非空行且行数小于100行时执行。当awk拿到第一行时(NR==1),定义了分隔符FS(FieldSeperate),这本来是在BEGINBlock中完成的(因为本例中的第一个if每次都会执行,浪费性能)。第二个if过滤掉注释语句,只有当NF(NumberofField)大于3时才执行。在awk中,NF表示每行用FS分隔后得到的Fields个数,相当于NF=line.split(财政司司长)。这个例子说明BEGIN和END只是语法糖,本质上和普通的Block是一样的。比如NF和FS都是awk的内置变量。Block的匹配条件中可以出现变量,同时可以修改内置变量的值来改变awk的行为。函数awk与AWKScript脚本一起工作。为了方便起见,awk提供了一些内置函数,以及允许您定义函数的函数。下面一行查找/etc/passwd文件第三列中的最大数字。函数find_max(n1,n2){如果(n1>n2){返回n1;}returnn2;}BEGIN{FS=":";max=-1;}{if(NF<3){next}#第一行max=$3;mR=NR;while(getline==1){_max=find_max(max,$3);如果(最大值<_最大值){最大值=_最大值;mR=NR;}}}END{打印“最大值为:”最大值;print"NRis:"mR;}然后执行awk-f./max.awk/etc/passwd.find_max是自定义函数,调用时需要括号,而getline和next是内置函数,调用内置函数不需要括号。其中,next用于跳过本次执行,主要用于处理文件开头的一些注释;getline用于获取下一行,getline会将下一行赋值给$x(x代表一个数字)。如果没有下一行并且while循环结束,则返回0。getline改变了awk的行为,awk从头到尾只执行一次Block。还有一些数学函数(如sin、cos、sqrt)和字符串操作函数(length、sprintf格式化字符串)都是内置函数。总结awk的可玩性很强,有了AWKScript,你可以用它来模拟其他常用的文本处理工具(谁会做?)参考链接https://www.ibm.com/developerworks/library/l-awk1/index。htmlhttps://www.gnu.org/software/gawk/manual/gawk.htmlmanawk
