AWKawk是一种程序语言.它具有一般程序语言常见的功能.因awk语言具有某些特点,如:使用直译器(Interpreter)不需先行编译;变量无类型之分(Typeless),可使用文字当数组的下标(AssociativeArray)...等特色.因此,使用awk撰写程序比起使用其它语言更简洁便利且节省时间.awk还具有一些内建功能,使得awk擅于处理具数据行(Record),字段(Field)型态的资料;此外,awk内建有pipe的功能,可将处理中的数据传送给外部的Shell命令加以处理,再将Shell命令处理后的数据传回awk程序,这个特点也使得awk程序很容易使用系统资源.由于awk具有上述特色,在问题处理的过程中,可轻易使用awk来撰写一些小工具;这些小工具并非用来解决整个大问题,它们只扮演解决个别问题过程的某些角色,可藉由Shell所提供的pipe将数据按需要传送给不同的小工具进行处理,以解决整个大问题.模式和动作任何awk语句都由模式和动作组成。模式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段BEGIN和END。动作即对数据的操作如打印、计算等域和记录awk执行时,其浏览域标记为$1,$2...$n。这种方法称为域标识。$0代表整条记录。域记录提示符单引号模式动作输入文件调用awk第一种是命令行方式:awk【-Ffiled-separator】‘commands’input-filesawk‘BEGIN{print“Goodafternoon”}{total+=$1}END{printtotal}’input-file第二种方法是将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它。chmodu+xprint.awk./print.awkinput-file第三种方式是将所有的awk命令插入一个单独文件,然后调用:awk–fprint.awkinput-file保存awk输出有两种方式保存shell提示符下awk脚本的输出。A、使用输出重定向符号文件名,下面的例子重定向输出到文件,使用这种方法要注意,显示屏上不会显示输出结果。awk‘{print$0}’chr10.snpchr10.newsnpB、第二种方法是使用tee命令,在输出到文件的同时输出到屏幕。awk‘{print$0}’chr10.snp|teechr10.newsnp常见应用打印所有记录和打印指定域awk‘{print$0}’example.txtawk‘{print$1,$4}’example.txt$1$4打印报告头和信息尾awk'BEGIN{printchr\tpos\tbase\tnum\tp-value}/chrX/{print}END{printendofthedata}'example.txt报告头信息尾BEGIN和ENDBEGIN和END部分在awk中都仅执行一次且有各自的用途如BEGIN用在程序一开始时,改变awk切割字段的方式、程序一开始时,改变awk分隔数据行的方式、设定变量的起始值、印出一行title、不需要读入任何数据行,而END用来打印结尾信息或者用来输出统计信息等awk‘{total+=$6}END{printtotal}’*.singlesingleawk'{total+=$6}END{printtotal}'*.soapsoapawk'BEGIN{total=100}{total+=$5}END{printtotal:,total}'example.txtawk中的数学运算符(ArithmeticOperators)+(加),-(減),*(乘),/(除),%(求余数),^(指数)与C语言中用法相同awk中的赋值运算符(AssignmentOperators)=,+=,-=,*=,/=,%=,^=x+=5的意思为x=x+5,其余类推.awk中的条件运算符(ConditionalOperator)语法:判断条件?value1:value2若判断条件成立(true)则返回value1,否则返回value2.awk中的逻辑运算符(LogicalOperators)&&(and),||(or),!(not)ExtendedRegularExpression中使用|表示or请勿混淆.awk中的关系运算符(RelationalOperators),=,,=,==,!=,~,!~awk中其它的运算符+(正号),-(负号),++(IncrementOperator),--(DecrementOperator)正则表达式正则表达式同perl中的正则表达式例:计算文件的大小(正则式的应用)匹配非目录文件末尾输出统计信息复合模式或复合操作符用于形成复杂的逻辑操作,复杂程度取决于编程者本人&&AND:语句两边必须同时匹配为真。||OR:语句两边同时或其中一边匹配为真。!非求逆awk'{if($490&&$50.5)print}'example.txtawk'{if($490||$50.5)print}'example.txt显示、修改文本域、显示修改记录、增加新的域和列正则匹配,选取文本修改域4注意:没有修改源文件的内容增加一个域6增加一行信息awk内置变量ARGC命令行参数个数ARGV命令行参数排列ENVIRON支持队列中系统环境变量的使用FILENAME浏览的文件名FNR浏览文件的记录数FS设置输入域分隔符,等价于命令行-F选项NF浏览记录的域个数NR已读的记录数OFS输出域分隔符ORS输出记录分隔符RS控制记录分隔符awk'END{printFILENAME,FNR,NR,NF}'example.txt连续读入多个文件的时候FNR和NR会有区别为什么?改变输出域的分割符改变输出域的分隔符,同时改变输出记录的分隔符处理多行的数据awk每次从数据文件中只读取一数据进行处理.awk是依照其内建变量RS(RecordSeparator)的定义将文件中的数据分隔成一行一行的Record.RS的默认值是“\n”(跳行符号),故平常awk中一行数据就是一笔Record.但有些文件中一笔Record涵盖了多行数据,这种情况下不能再以“\n”来分隔Records.最常使用的方法是相邻的Records之间改以一个空白行来隔开.在awk程序中,令RS=(空字符串)后,awk把会空白行当成来文件中Record的分隔符.多个空行改变域和记录的默认分隔符如何读取命令行上的参数大部分的应用程序都允许使用者在命令之后增加一些选择性的参数.执行awk时这些参数大部分用于指定数据文件文件名,有时希望在程序中能从命令行上得到一些其它用途的数据.ARGC:为一整数.代表命令行上,除了选项-v,-f及其对应的参数之外所有参数的数目;ARGV[]:为一字符串数组.ARGV[0],ARGV[1],...ARGV[ARGC-1].分别代表命令行上相对应的参数.awk强大的内置字符串函数gsub(r,s)在整个$0中用s替代rgsub(r,s,t)在整个t中用s替代rindex(s,t)返回s中字符串t的第一位置length(s)返回s长度match(s,r)测试s是否包含匹配r的字符串split(s,a,fs)在fs上将s分成序列asprint(fmt,exp)返回经fmt格式化后的expsub(r,s)用$0中最左边最长的子串代替ssubstr(s,p)返回字符串s中从p开始的后缀部分substr(s,p,n)返回字符串s中从p开始长度为n的后缀部分格式化输出1、awkprintf修饰符-左对齐Width域的步长,用0表示0步长.prec最大字符串长度,或小数点右边的位数2、awkprintf格式%cASCII字符%d整数%e浮点数,科学记数法%f浮点数,例如(123.44)%gawk决定使用哪种浮点数转换e或者f%o八进制数%s字符串%x十六进制数向一行awk命令传值awk命令变量=输入文件值变量赋值管道传值awk数组和awk脚本split函数,使用它将元素划分进一个数组,例如split返回数组myarray下标数。数组使用前,不必定义,也不必指定数组元素个数,而且可以使用字符串当数组的下标(index)。经常使用循环来访问数组。下面是一种循环类型的基本结构:返回数组myarray,数组中有三个元素遍历数组,逐个输出数组中的元素awk脚本就是把命令行上的单引号之间的部分写到脚本中就可以了例如awk‘{print$0}’input-file写到脚本中如下#!/bin/sh-f{print$0}这样就可以调用了详见下例字符串下标加可执行权限awk程序中使用Shell命令awk程序中允许呼叫Shell指令.并提供管道解决awk与系统间数据传递的问题.所以awk很容易使用系统资源.自定义函数awk中亦允许使用者自定函数.函数定义方式请参考本程序,function为awk的保留字.HM_to_M()这函数负责将所传入之小时及分钟数转换成以分钟为单位.使用者自定函数时,有许多细节须留心修改字段分隔符自定义函数调用自定义函数三目操作符sort排序打印soap文件的最后一列去除所有的非ATCG的字符统计所有的ATCG字符for循环实现多文件处理流程控制指令if指令语法if(表达式)语句1[else语句2]范例:if($125)printThe1stfieldislargerthan25elseprintThe1stfieldisnotlargerthan25(a)与C语言中相同,若表达式计算(evaluate)后之值不为0或空字符串,则执行语句1;否则执行语句2.(b)进行逻辑判断的表达式所返回的值有两种,若最后的逻辑值为true,则返回1,否则返回0.(c)语法中else语句2以[]前后括住表示该部分可视需要而予加入或省略.while指令语法:while(表达式)语句范例:while(match(buffer,/[0-9]+\.c/)){printFind:substr(buffer,RSTART,RLENGTH)buff=substr(buffer,RSTART+RLENGTH)}上列范例找出buffer中所有能匹配/[0-9]+.c/(数字之后接上.c的所有子字符串).范例中while以函数match()所返回的值做为判断条件.若buffer中还含有匹配指定条件的子字符串(match成功),则match()函数返回1,while将持续进行其后的语句.do-while指令语法:do语句while(表达式)范例:do{printEnteryorn!getlinedata}while(data!~/^[YyNn]$/)(a)上例要求用户从键盘上输入一个字符,若该字符不是Y,y,N,或n则会不停执行该循环,直到读取正确字符为止.(b)do-while指令与while指令最大的差异是:do-while指令会先执行statement而后再判断是否应继续执行.所以,无论如何其statement部分至少会执行一次.forStatement指令(一)语法:for(variableinarray)statement范例:执行下列命令awk‘BEGIN{X[1]=50;X[2]=60;X[last]=70for(anyinX)printf(X[%s]=%d\n,any,X[any])}'结果输出:X[last]=70X[1]=50X[2]=60(a)这个for指令,专用以查找数组中所有的下标值,并依次使用所指定的变量予以记录.以本例而言,变量any将逐次代表last,1及2.(b)以这个for指令,所查找出的下标之值彼此间并无任何次续关系.forStatement指令(二)语法:for(expression1;expression2;expression3)statement范例:for(i=1;i=10;i++)sum=sum+i说明:(a)上列范例用以计算1加到10的总和.(b)e