搜索
您的当前位置:首页正文

AWK教程

来源:小奈知识网
0.awk有3个不同版本:awk、nawk和gawk,未作特别说明,一般指gawk。

1.awk语言的最基本功能是在文件或字符串中基于指定规则来分解抽取信息,也可以基于指定的规则来输出数据。完整的awk脚本通常用来格式化文本文件中的信息。

2.三种方式调用awk

1)awk[opion]'awk_script'input_file1[input_file2...]awk的常用选项option有:

①-Ffs:使用fs作为输入记录的字段分隔符,如果省略该选项,awk使用环境变

量IFS的值。

②-ffilename:从文件filename中读取awk_script。③-vvar=value:为awk_script设置变量。

2)将awk_script放入脚本文件并以#!/bin/awk-f作为首行,给予该脚本可执行权限,然后在shell下通过键入该脚本的脚本名调用之。

3)将所有的awk_script插入一个单独脚本文件,然后调用:awk-fawk脚本文件input_file(s)。

3.awk的运行过程

1)awk_script的组成:

①awk_script可以由一条或多条awk_cmd组成,两条awk_cmd之间一般以

NEWLINE分隔。

②awk_cmd由两部分组成:awk_pattern{actions}

③awk_script可以被分成多行书写,必须确保整个awk_script被单引号括起来。2)awk命令的一般形式:awk'BEGIN{actions}awk_pattern1{actions}............awk_patternN{actions}END{actions}'inputfile其中BEGIN{actions}和END{actions}是可选的。

3)awk的运行过程:

①如果BEGIN区块存在,awk执行它指定的actions。

②awk从输入文件中读取一行,称为一条输入记录。(如果输入文件省略,将从标

准输入读取)。

③awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2,

以此类推。$0表示整条记录。字段分隔符使用shell环境变量IFS或由参数指定。

④把当前输入记录依次与每一个awk_cmd中awk_pattern比较,看是否匹配,如果相匹配,就执行对应的actions。如果不匹配,就跳过对应的actions,直到比较完所有的awk_cmd。

⑤当一条输入记录比较了所有的awk_cmd后,awk读取输入的下一行,继续重复

步骤③和④,这个过程一直持续,直到awk读取到文件尾。

⑥当awk读完所有的输入行后,如果存在END,就执行相应的actions。

4)iput_file可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。5)一条awk_cmd的awk_pattern可以省略,省略时不对输入记录进行匹配比较就执行相应的actions。一条awk_cmd的actions也可以省略,省略时默认的动作为打印当前输入记录(print$0)。一条awk_cmd中的awk_pattern和actions不能同时省略。

6)BEGIN区块和END区块别位于awk_script的开头和结尾。awk_script中只有END区块或者只有BEGIN区块是被允许的。如果awk_script中只有BEGIN{actions},awk不会读取input_file。

7)awk把输入文件的数据读入内存,然后操作内存中的输入数据副本,awk不会修改输入文件的内容。

8)awk的总是输出到标准输出,如果想让awk输出到文件,可以使用重定向。4.awk_patternawk_pattern模式部分决定actions动作部分何时触发及触发actions。awk_pattern可以是以下几种类型:

1)正则表达式用作awk_pattern:/regexp/

①awk中正则表达式匹配操作中经常用到的字符:\\^$.[]|()*//通用的regexp元

字符+:匹配其前的单个字符一次以上,是awk自有的元字符,不适用于grep或sed等。?:匹配其前的单个字符1次或0次,是awk自有的元字符,不适用于grep或sed等

②举例:awk'/*\\$0\\.[0-9][0-9].*/'input_file

2)布尔表达式用作awk_pattern,表达式成立时,触发相应的actions执行。

①表达式中可以使用变量(如字段变量$1,$2等)和/regexp/

②布尔表达式中的操作符:关系操作符:<><=>===!=匹配操作符:value~/regexp/如果value匹配/regexp/,则返回真value!~/regexp/如果value不匹配/regexp/,则返回真举例:awk'$2>10{print\"ok\input_fileawk'$3~/^d/{print\"ok\input_file

③&&(与)和||(或)可以连接两个/regexp/或者布尔表达式,构成混合表达式。!(非)

可以用于布尔表达式或者/regexp/之前。举例:awk'($1<10)&&($2>10){print\"ok\input_fileawk'/^d/||/x$/{print\"ok\input_file

④其它表达式用作awk_script,如赋值表达式等eg:awk'(tot+=$6);END{print

\"totalpoints:\"tot}'input_file//分号不能省略awk'tot+=$6{print$0}END{print\"totalpoints:\"tot}'input_file//与上面等效

5.actions

actions就是对awk读取的记录数据进行的操作。actions由一条或多条语句或者命令组成,语句、命令之间用分号(;)分隔。actions中还可以使用流程控制结构的语句。

1)awk的命令:

①print参数列表:print可以打印字符串(加双引号)、变量和表达式,是awk最基

本的命令。参数列表要用逗号(,)分隔,如果参数间用空格分隔,打印出时参数值之间不会有空格。

②printf([格式控制符],参数):格式化打印命令(函数),语法与C语言的printf函

数类似。

③next:强迫awk立刻停止处理当前的记录,而开始读取和处理下一条记录。

④nextfile:强迫awk立刻停止处理当前的输入文件而处理输入文件列表中的下一

个文件

⑤exit:使awk停止执行而跳出。如果有END存在,awk会去执行END的actions。2)awk的语句:awk的语句主要是赋值语句,用来给变量赋值。

①把直接值或一个变量值赋值给变量。如果直接值是字符串要加双引号。举例:

awk'BEGIN{x=1;y=3;x=y;print\"x=\"x\";y=\"y}'

②把一个表达式的值赋值给变量。表达式一般是数值表达式,也可以是其它表达

式。数值表达式:num1operatornum2operator可以是:+(加)-(减)*(乘)/(除)%(取模)^(求幂)当num1或者num2是字符串而是不是数字时,无论是否加有双引号,awk都视其值为0条件选择表达式:A?B:C(A为布尔表达式,B和C可以是表达式或者直接值)当布尔表达式A的值为真时,整个表达式的值为B,A的值为假时,整个表达式的值为C举例:awk'BEGIN

{x=3;x+=2;y=x+2;print\"x=\"x\";y=\"y}'awk'BEGIN{x=3;y=x>4?\"ok\":4;print\"x=\"x\";y=\"y}'

③为了方便书写,awk也支持C语言语法的赋值操作符:+=-=*=/=%=^=++--3)

流程控制结构(基本上是使用C语言的语法)其中condition一般为布尔表达式,body和else-body是awk语句块。

①if(condition){then-body}[else{else-body}]②while(condition){body}③do{body}while(condition)

④for(initialization;condition;increment){body}与C语言的for结构的语法相同⑤break:跳出包含它的for、while、do-while循环

⑥continue:跳过for、while、do-while循环的body的剩余部分,而立刻进行下一

次循环的执行。6.awk的变量

在awk_script中的表达式中要经常使用变量。不要给变量加双引号,那样做,awk将视之为字符串。awk的变量基本可以分为两类:

1)awk内部变量:awk的内部变量用于存储awk运行时的各种参数,这些内部变量又可以分为:

①自动内部变量:这些变量的值会随着awk程序的运行而动态的变化,在

awk_script中改变这些变量的值是没有意义的(即不应该被赋值)。常见的有:NF:当前输入字段的字段数NR:对当前输入文件而言,已经被awk读取过的记录(行)的数目。FNR:已经被awk读取过的记录(行)的总数目。当输入文件只有一个时,FNR和NR是一致的。FILENAME:当前输入文件的文件名。ARGC:命令行参数个数。(不包括选项和awk_script,实际就是输入文件的数目加1)ARGIND:当前被处理的文件在数组ARGV内的索引(实际上ARGV[1]就是第一个输入文件)举例:awk'{printNR,NF,$0}END{printFILENAME}'input_file

②字段变量($0$1$2$3...):当awk把当前输入记录分段时,会对这些字段变量赋

值。和内部变量类似,在awk运行过程中字段变量的值是动态变化的。不同的是,修改这些字段变量的值是有意义的,被修改的字段值可以反映到awk的输出中。可以创建新的输出字段,比如,当前输入记录被分割为8个字段,这时可以通过对变量$9(或$9之后的字段变量)赋值而增加输出字段,NR的值也将随之变化。字段变量支持变量名替换。举例:pwd|awk-F/'{print$NF}'//print$NF打印输入记录的最后一个字段awk'{x=2;print$x}'input_file//打印输入记录的第2个字段

③其它内部变量:可以修改这些变量。常见的有:FS:输入记录的字段分隔符(默

认是空格和制表符)OFS:输出记录的字段分隔符(默认是空格)OFMT:数字的输出格式(默认是%.6g)RS:输入记录间的分隔符(默认是NEWLINE)ORS:输出记录间的分隔符(默认是NEWLINE)ARGV:命令行参数数组ENVIRON:存储系统当前环境变量值的数组,它的每个成员的索引就是一个环境变量名,而对应的值就是相应环境变量的值。可以通过给ENVIRON数组的成员赋值而改变环境变量的值,但是新值只在awk_script内有效。eg:ENVIRON[\"HISTSIZE\"]=500举例:cat/etc/passwd|awk'BEGIN{FS=\":\"}{print\"Username:\"$1,\"UID:\"$4}'

2)自定义变量

1)定义变量:varname=value(自定义变量不需先声明后使用,赋值语句同时完成变

量定义和初始化)

2)在表达式中出现不带双引号的字符串都被视为变量,如果之前未被赋值,默认

值为0或空字符串。

3)向命令行awk程序传递变量的值:

①Usage:awk'awk_script'awkvar1=value1awkvar2=value2....input_fileeg:awk'{if($5②awkvar可以是awk内置变量或自定义变量。

③awkvar的值将在awk开始对输入文件的第一条记录应用awk_script前传入。

如果在awk_script中已经对某个变量赋值,那么在命令行上传人到该变量的值就会无效(实际上是awk_script中的赋值语句覆盖了从命令行上传入的值)。

④在awk脚本程序中不能直接使用shell的变量。通过使用下面的语法可达到

这样的效果。awk'awk_script'awkvar1=shellvar1awkvar2=shellvar2....input_fileeg:awk'{if(v1==\"root\"){print\"Usernameisroot!\v1=$USERinput_file

⑤可以向awk脚本传递变量的值,与上面的类似。awk_script_file

awkvar1=value1awkvar2=value2...input_file

7.awk的内置函数

可以在awk_script的任何地方使用awk函数。和awk变量一样,awk函数可以分为内置函数和自定义函数。

1)常见awk内置数值函数int(x):求出x的整数部份,朝向0的方向做舍去。eg:int(3.9)是3,int(-3.9)是-3。sqrt(x):求出x正的平方根值。eg:sqrt(4)=2exp(x):求出x的次方。eg:exp(2)即是求e*e。log(x):求出x的自然对数。sin(x):求出x的sine值,x是弪度量。cos(x):求出x的cosine值,x是弪度量。atan2(y,x):求y/x的arctangent值,所求出的值其单位是弪度量。rand():得到一个随机数(平均分布在0和1之间)。每次执行gawk,rand从相同的seed生成值。srand(x):设定产生随机数的seed为x。如果在第二次运行awk程序时你设定相同的seed值,你将再度得到相同序列的随机数。如果省略引数x,例如srand(),则当前日期时间会被当成seed。这个方法可使得随机数值是真正不可预测的。srand():其值是当次awk_script运行过程中前次srand(x)的设定的seed值x,。

2)常见awk内置字符串函数index(in,find):返回字符串in中字符串find第一次出现的位置(索引从1开始),如果在字串in中找不到字符串find,则返回值为0。eg:printindex(\"peanut\会印出3。length(s):求出字符串s的字符个数。eg:length(\"abcde\")是5。match(s,r):返回模式字符串r在字符串s的第一次出现的位置,如果s不包含r,则返回值0。sprintf(fmt,exp1,...):和printf类似印出,是sprintf不是打印而是返回经fmt格式化后的exp。eg:sprintf(\"pi=%.2f(approx.)\传回的字串为\"pi=3.14(approx.)\"sub(p,r,t):在字符串t中寻找符合模式字符串p的最靠前最长的位置,并以字符串r代替最前的p。eg:str=\"water,water\"sub(/at/,\"ith\结果字符串str会变成\"wither,water\"gsub(p,r,t):gsub与sub类似。不过时在字符串t中以字符串r代替所有的p。eg:str=\"water,water\";gsub(/at/,\"ith\结果字符串str会变成\"wither,wither\"substr(str,st,len):传回str的子字符串,其长度为len字符,从str的第st个位置开始。如果len没有出现,则传回的子字符串是从第st个位置开始至结束。eg:substr(\"washington\传回值为\"ing\"substr(\"washington\传回值为\"ington\"split(s,a,fs):在分隔符fs为分隔符将字符串s分隔成一个awk数组a,并返回a的下标数。eg:awk'BEGIN{printsplit(\"123#456#789\将打印3。tolower(str):将字符串str的大写字母改为小写字母。eg:tolower(\"MiXeDcAsE123\")传回值为\"mixedcase123\"toupper(str):将字符串string的小写字母改为大写字母。eg:toupper(\"MiXeDcAsE123\")传回值为\"MIXEDCASE123\"3)常见awk内置系统函数

close(filename):将输入或输出的文件filename关闭。system(command):此函数允许调用操作系统的指令,执行完毕後将回到awk程序。eg:awk'BEGIN{system(\"ls\")}'8.自定义函数

复杂的awk常常可以使用自己定义的函数来简化。调用自定义的函数与调用内置函数的方法一样。

1)自定义函数定义的格式:自定义函数可以在awk程序的任何地方定义。functionfun_name(parameter_list){//parameter_list是以逗号分隔的参数列表body-of-function//函数体,是awk语句块}

2)举例:awk'{print\"sum=\}functionSquareSum(x,y){sum=x*x+y*y;returnsum}'grade.txt9.awk的数组数组使用前,不必预先定义,也不必指定数组元素个数。1)访问数组的元素。经常使用循环来访问数组元素,下面是一种循环类型的基本结构:for(elementinarray_name)printarray_name[element]2)举例:awk'BEGIN{printsplit(\"123#456#789\;for(iinmya){printmya[i]}}'

10.其他

1)为了避免碰到awk错误,可以总结出以下规律:

①确保整个awk_script用单引号括起来。②确保awk_script内所有引号成对出现。

③确保用花括号括起动作语句,用圆括号括起条件语句。

④可能忘记使用花括号,也许你认为没有必要,但awk不这样认为,将按之解释

语法。

⑤如果使用字符串,一定要保证字符串被双引号括起来(在模式中除外)。

2)在awk中,设置有意义的域名是一种好习惯,在进行模式匹配或关系操作时更容易理解。一般的变量名设置方式为name=$n。(这里name为调用的域变量名,n为实际域号。)

3)通常在BEGIN部分给一些变量赋值是很有益的,这样可以在awk表达式进行改动时减少很多麻烦。

4)awk的基本功能是根据指定规则抽取输入数据的部分内容并输出,另一个重要的功能是对输入数据进行分析运算得到新的数据并输出,这是通过在awk_script中对字段变量($1、$2、$3...)从新赋值或使用更大的字段变量$n(n大于当前记录的NF)而实现的。

5)使用字符串或正则表达式时,有时需要在输出中加入一新行或查询一元字符。这时就需要字符串屏蔽序列。awk中经常使用的屏蔽序列有:\\b退格键\tab键\\f走纸换页\\ddd八进制值\\n新行\\r回车键\\c任意其他特殊字符。eg:\\\\为反斜线符号6)awk的输出函数printf,基本上和C语言的语法类似。

①格式:printf(\"输出模板字符串\参数列表)

②参数列表是以逗号分隔的列表,参数可以是变量、数字值或字符串。

③输出模板字符串的字符串中必须包含格式控制符,有几个参数就要求有几个格式控制符。模板字符串中可以只有格式控制符而没有其它字符。

④格式控制符:%[-][width][.prec]fmt%:标识一个格式控制符的开始,不可省略。-:表示参数输出时左对齐,可省略。width:一个数字,表示参数输出时占用域的宽度,可省略。.prec:prec是一个数值,表示最大字符串长度或小数点右边的位数,可省略。fmt:一个小写字母,表示输出参数的数据类型,不可省略。

⑤常见的fmt:cASCII字符d整数e浮点数,科学记数法f浮点数,如123.44g由awk决定使用哪种浮点数转换e或fo八进制数s字符串x十六进制数

⑥举例:echo\"65\"|awk'{printf(\"%c\\n\}'//将打印Aawk'BEGIN{printf\"%.4f\\n\//将打印999.0000awk'BEGIN{printf\"2number:%8.4f%8.2f\//将打印2number:999.0000888.000

因篇幅问题不能全部显示,请点此查看更多更全内容

Top