1、AWK 命令说明命令说明 AWK命令 Table of Contents:1.awk简介 2.awk命令格式和选项 2.1.awk的语法有两种形式 2.2.命令选项 3.模式和操作 3.1.模式 3.2.操作 4.awk的环境变量 5.awk运算符 6.记录和域 6.1.记录 6.2.域 6.3.域分隔符 7.gawk专用正则表达式元字符 8.POSIX字符集 9.匹配操作符()10.比较表达式 11.范围模板 12.一个验证 passwd 文件有效性的例子 13.几个实例 14.awk编程 14.1.变量 14.2.BEGIN 模块 14.3.END模块 14.4.重定向和管道 14.5.条
2、件语句 14.6.循环 14.7.数组 14.8.awk的内建函数 15.How-to 1.awk简介:awk是一种编程语言,用于在 linux/unix 下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是 linux/unix 下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk 的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的
3、行都被处理。awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是 Alfred Aho、Brian Kernighan、Peter Weinberger。gawk 是 awk的GNU版本,它提供了 Bell 实验室和 GNU的一些扩展。下面介绍的 awk 是以 GUN的gawk为例的,在 linux 系统中已把 awk链接到 gawk,所以下面全部以 awk 进行介绍。2.awk命令格式和选项:2.1.awk的语法有两种形式:awk options script var=value file(s)awk options-f scriptfile var=value file(s)
4、2.2.命令选项:-F fs or-field-separator fs 指定输入文件折分隔符,fs 是一个字符串或者是一个正则表达式,如-F:。-v var=value or-asign var=value 赋值一个用户定义变量。-f scripfile or-file scriptfile 从脚本文件中读取 awk 命令。-mf nnn and-mr nnn 对 nnn值设置内在限制,-mf选项限制分配给 nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是 Bell 实验室版 awk 的扩展功能,在标准 awk 中不适用。-W compact or-compat,-W trad
5、itional or-traditional 在兼容模式下运行 awk。所以 gawk的行为和标准的 awk完全一样,所有的 awk扩展都被忽略。-W copyleft or-copyleft,-W copyright or-copyright 打印简短的版权信息。-W help or-help,-W usage or-usage 打印全部 awk选项和每个选项的简短说明。-W lint or-lint 打印不能向传统 unix 平台移植的结构的警告。-W lint-old or-lint-old 打印关于不能向传统 unix 平台移植的结构的警告。-W posix 打开兼容模式。但有以下限制
6、,不识别:x、函数关键字、func、换码序列以及当fs 是一个空格时,将新行作为一个域分隔符;操作符*和*=不能代替和=;fflush 无效。-W re-interval or-re-inerval 允许间隔正则表达式的使用,参考(grep中的 Posix 字符类),如括号表达式:alpha:。-W source program-text or-source program-text 使用 program-text 作为源代码,可与-f命令混用。-W version or-version 打印 bug报告信息的版本。3.模式和操作:awk脚本是由模式和操作组成的:pattern action
7、如$awk/root/test,或$awk$3%1选择第二个字段比第一个字段长的行。模式匹配表达式:用运算符(匹配)和!(不匹配)。模式,模式:指定一个行的范围。该语法不能包括 BEGIN 和 END 模式。BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。END:让用户在最后一条输入记录被读取之后发生的动作。3.2.操作:操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份。变量或数组赋值 输出命令 内置函数 控制流命令 4.awk的环境变量:Table 1.awk的环境变量 变量 描述$n 当前记录的第 n 个字
8、段,字段间由 FS 分隔。$0 完整的输入记录。ARGC 命令行参数的数目。ARGIND 命令行中当前文件的位置(从 0 开始算)。ARGV 包含命令行参数的数组。CONVFMT 数字转换格式(默认值为%.6g)ENVIRON 环境变量关联数组。ERRNO 最后一个系统错误的描述。FIELDWIDTHS 字段宽度列表(用空格键分隔)。FILENAME 当前文件名。FNR 同 NR,但相对于当前文件。FS 字段分隔符(默认是任何空格)。IGNORECASE 如果为真,则进行忽略大小写的匹配。NF 当前记录中的字段数。NR 当前记录数。OFMT 数字的输出格式(默认值是%.6g)。OFS 输出字段
9、分隔符(默认值是一个空格)。ORS 输出记录分隔符(默认值是一个换行符)。RLENGTH 由 match 函数所匹配的字符串的长度。RS 记录分隔符(默认是一个换行符)。RSTART 由 match 函数所匹配的字符串的第一个位置。SUBSEP 数组下标分隔符(默认值是034)。5.awk运算符 Table 2.运算符 运算符 描述 =+=-=*=/=%=*=赋值?:C 条件表达式|逻辑或&逻辑与 !匹配正则表达式和不匹配正则表达式 =!=关系运算符 空格 连接 +-加,减 */&乘,除与求余 +-!一元加,减和逻辑非 *求幂 +-增加或减少,作为前缀或后缀$字段引用 in 数组成员 6.记录
10、和域 6.1.记录 awk把每一个以换行符结束的行称为一个记录。记录分隔符:默认的输入和输出的分隔符都是回车,保存在内建变量 ORS 和 RS中。$0变量:它指的是整条记录。如$awk print$0 test 将输出 test 文件中的所有记录。变量 NR:一个计数器,每处理完一条记录,NR 的值就增加 1。如$awk print NR,$0 test 将输出 test 文件中所有记录,并在记录前显示记录号。6.2.域 记录中每个单词称做“域”,默认情况下以空格或 tab分隔。awk可跟踪域的个数,并在内建变量 NF中保存该值。如$awk print$1,$3 test 将打印 test 文
11、件中第一和第三个以空格分开的列(域)。6.3.域分隔符 内建变量 FS 保存输入域分隔符的值,默认是空格或 tab。我们可以通过-F命令行选项修改 FS 的值。如$awk-F:print$1,$5 test 将打印以冒号为分隔符的第一,第五列的内容。可以同时使用多个域分隔符,这时应该把分隔符写成放到方括号中,如$awk-F:t print$1,$3 test,表示以空格、冒号和 tab作为分隔符。输出域的分隔符默认是一个空格,保存在 OFS 中。如$awk-F:print$1,$5 test,$1 和$5间的逗号就是 OFS 的值。7.gawk专用正则表达式元字符 一般通用的元字符集就不讲了,
12、可参考我的 Sed 和 Grep学习笔记。以下几个是gawk专用的,不适合 unix 版本的 awk。Y 匹配一个单词开头或者末尾的空字符串。B 匹配单词内的空字符串。匹配一个单词的末尾的空字符串,锚定末尾。w 匹配一个字母数字组成的单词。W 匹配一个非字母数字组成的单词。匹配字符串开头的一个空字符串。匹配字符串末尾的一个空字符串。8.POSIX字符集 可参考我的 Grep学习笔记 9.匹配操作符()用来在记录或者域内匹配正则表达式。如$awk$1/root/test 将显示 test 文件第一列中以 root开头的行。10.比较表达式 conditional expression1?expr
13、ession2:expression3,例如:$awk max=$1$3?$1:$3:print max test。如果第一个域大于第三个域,$1就赋值给 max,否则$3就赋值给 max。$awk$1+$2 5&$2 10 test,如果第一个域大于 5,并且第二个域小于 10,则打印这些行。11.范围模板 范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,则匹配到开头或末尾。如$awk/root/,/mysql/test 将显示root第一次出现到 mysql 第一次出现之间的所有行。12.一个验证 passwd 文件有效性的例子$cat/etc
14、/passwd|awk-F:NF!=7 printf(line%d,does not have 7 fields:%sn,NR,$0)$1!/A-Za-z0-9/printf(line%d,non alpha and numeric user id:%d:%sn,NR,$0)$2=*printf(line%d,no password:%sn,NR,$0)cat 把结果输出给 awk,awk把域之间的分隔符设为冒号。如果域的数量(NF)不等于 7,就执行下面的程序。printf打印字符串line?does not have 7 fields,并显示该条记录。如果第一个域没有包含任何字母和数字,p
15、rintf打印“no alpha and numeric user id,并显示记录数和记录。如果第二个域是一个星号,就打印字符串“no passwd”,紧跟着显示记录数和记录本身。13.几个实例$awk/(no|so)/test-打印所有以模式 no 或 so 开头的行。$awk/ns/print$1 test-如果记录以 n 或 s 开头,就打印这个记录。$awk$1/0-90-9$/(print$1 test-如果第一个域以两个数字结束就打印这个记录。$awk$1=100|$2 5?ok$1:error$1)test-如果第一个域大于 5 则打印问号后面的表达式值,否则打印冒号后面的表达
16、式值。$awk/root/,/mysql/test-打印以正则表达式 root开头的记录到以正则表达式mysql 开头的记录范围内的所有记录。如果找到一个新的正则表达式 root 开头的记 录,则继续打印直到下一个以正则表达式 mysql 开头的记录为止,或到文件末尾。14.awk编程 14.1.变量 在 awk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串。赋值格式:Variable=expression,如$awk$1/test/count=$2+$3;print count test,上式的作用是,awk 先扫描第一个域,一旦 test 匹配,就把第二个域的值加上第三个域的
17、值,并把结果赋值给变量 count,最后打印出来。awk可以在命令行中给变量赋值,然后将这个变量传输给 awk脚本。如$awk-F:-f awkscript month=4 year=2004 test,上式的 month 和 year都是自定义变量,分别被赋值为 4 和 2004。在 awk 脚本中,这些变量使用起来就象是在脚本中建立的一样。注意,如 果参数前面出现 test,那么在 BEGIN 语句中的变量就不能被使用。域变量也可被赋值和修改,如$awk$2=100+$1;print test,上式表示,如果第二个域不存在,awk将计算表达式 100加$1的值,并将其赋值给$2,如果第二个
18、域存在,则用表达式的值覆盖$2原来的值。再例如:$awk$1=root$1=test;print test,如果第一个域的值是“root”,则把它赋值为“test”,注意,字符串一定要用双引号。内建变量的使用。变量列表在前面已列出,现在举个例子说明一下。$awk-F:IGNORECASE=1;$1=MARYprint NR,$1,$2,$NFtest,把 IGNORECASE 设为 1代表忽略大小写,打印第一个域是 mary的记录数、第一个域、第二个域和最后一个 域。14.2.BEGIN 模块 BEGIN 模块后紧跟着动作块,这个动作块在 awk处理任何输入文件之前执行。所以它可以在没有任何输
19、入的情况下进行测试。它通常用来改变内建变量的值,如OFS,RS 和 FS 等,以及打印标题。如:$awk BEGINFS=:;OFS=t;ORS=nnprint$1,$2,$3 test。上式表示,在处理输入文件以前,域分隔符(FS)被设为冒号,输出文件分隔符(OFS)被设置为制表符,输出记录分隔符(ORS)被设置为两个 换行符。$awk BEGINprint TITLE TEST只打印标题。14.3.END模块 END不匹配任何的输入文件,但是执行动作块中的所有动作,它在整个输入文件处理完成后被执行。如$awk ENDprint The number of records is NR tes
20、t,上式将打印所有被处理的记录数。14.4.重定向和管道 awk可使用 shell 的重定向符进行重定向输出,如:$awk$1=100 print$1 output_file test。上式表示如果第一个域的值等于 100,则把它输出到 output_file中。也可以用来重定向输出,但不清空文件,只做追加 操作。输出重定向需用到 getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内 容,并给 NF,NR 和FNR 等内建变量赋值。如果得到一条记录,getline函数返回 1,如果到达文件的末尾就返回 0,如果出现错误,
21、例如打开文件失 败,就返回-1。如:$awk BEGIN date|getline d;print d test。执行 linux 的 date命令,并通过管道输出给 getline,然后再把输出赋值给自定义变量 d,并打印它。$awk BEGINdate|getline d;split(d,mon);print mon2 test。执行 shell 的 date命令,并通过管道输出给 getline,然后 getline从管道中读取并将输入赋值给 d,split函数把变量 d转 化成数组 mon,然后打印数组 mon 的第二个元素。$awk BEGINwhile(ls|getline)pri
22、nt,命令 ls 的输出传递给 geline作为输入,循环使 getline从 ls 的输出中读取一行,并把它打印到屏幕。这里没有输入文件,因为 BEGIN 块在打开输入文件前执行,所以可以忽略输入文件。$awk BEGINprintf What is your name?;getline name /dev/tty$1 name print Found name on line,NR.ENDprint See you,name.test。在屏幕上打印”What is your name?,并等待用户应答。当一行输入完毕后,getline 函数从终端接收该行输入,并把它储存在自定义变量 nam
23、e中。如果第一个域匹配变量 name的值,print 函数就被执行,END 块打印 See you 和 name 的值。$awk BEGINwhile(getline 0)lc+;print lc。awk 将逐行读取文件/etc/passwd的内容,在到达文件末尾前,计数器 lc一直增加,当到末尾时,打印 lc的值。注意,如果文件不存 在,getline返回-1,如果到达文件的末尾就返回 0,如果读到一行,就返回 1,所以命令 while(getline /etc/passwd)在文件不存在的情况下将陷入无限循环,因为返回-1 表示逻辑真。可以在 awk中打开一个管道,且同一时刻只能有一个管道
24、存在。通过 close()可关闭管道。如:$awk print$1,$2|sort test END close(sort)。awd 把 print 语句的输出通过管道作为 linux 命令 sort的输入,END块执行关闭管道操作。system 函数可以在 awk 中执行 linux 的命令。如:$awk BEGINsystem(clear)。fflush 函数用以刷新输出缓冲区,如果没有参数,就刷新标准输出的缓冲区,如果以空字符串为参数,如 fflush(),则刷新所有文件和管道的输出缓冲区。14.5.条件语句 awk中的条件语句是从 C 语言中借鉴过来的,可控制程序的流程。14.5.1.
25、if语句 格式:if(expression)statement;statement;.$awk if($1$2)print$2 too high test。如果第一个域小于第二个域则打印。$awk if($1 100)print$1 bad;else print ok test。如果$1大于 100 则打印$1 bad,否则打印 ok。$awk if($1 100)count+;print$1 else count-;print$2 test。如果$1大于100,则 count 加一,并打印$1,否则 count 减一,并打印$1。14.5.3.if/else else if 语句,用于多重判
26、断。格式:if(expression)statement;statement;.else if(expression)statement;statement;.else if(expression)statement;statement;.else statement;statement;.14.6.循环 awk有三种循环:while 循环;for循环;special for循环。$awk i=1;while(i=NF)print NF,$i;i+test。变量的初始值为 1,若 i 小于可等于 NF(记录中域的个数),则执行打印语句,且 i 增加 1。直到 i 的值大于 NF.$awk fo
27、r(i=1;iNF;i+)print NF,$i test。作用同上。breadkcontinue 语句。break 用于在满足条件的情况下跳出循环;continue用于在满足条件的情况下忽略后面的语句,直接返回循环的顶端。如:for(x=3;x=NF;x+)if($x0)print Bottomed out!;break for(x=3;x=NF;x+)if($x=0)print Get next item;continue next 语句从输入文件中读取一行,然后从头开始执行 awk脚本。如:if($1/test/)next else print exit 语句用于结束 awk程序,但不会
28、略过 END块。退出状态为 0 代表成功,非零值表示出错。14.7.数组 awk中的数组的下标可以是数字和字母,称为关联数组。14.7.1.下标与关联数组 用变量作为数组下标。如:$awk namex+=$2;ENDfor(i=0;iNR;i+)print i,name test。数组 name 中的下标是一个自定义变量 x,awk初始化 x 的值为 0,在每次使用后增加 1。第二个域的值被赋给 name 数组的各个元素。在 END 模块中,for循环被用于循环整个数组,从下标为 0的元素开始,打印那些存储在数组中的值。因为下标是关健字,所以它不一定从 0开始,可以从任何值开始。special
29、 for循环用于读取关联数组中的元素。格式如下:for(item in arrayname)print arraynameitem$awk/tom/nameNR=$1;ENDfor(i in name)print name test。打印有值的数组元素。打印的顺序是随机的。用字符串作为下标。如:counttest 用域值作为数组的下标。一种新的 for循环方式,for(index_value in array)statement。如:$awk count$1+ENDfor(name in count)print name,countname test。该语句将打印$1 中字符串出现的次数。它首
30、先以第一个域作数组 count 的下标,第一个域变化,索引就变化。delete函数用于删除数组元素。如:$awk linex+=$1 ENDfor(x in line)delete(linex)test。分配给数组 line的是第一个域的值,所有记录处理完成后,special for循环将删除每一个元素。14.8.awk的内建函数 14.8.1.字符串函数 sub 函数匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。格式如下:sub(regular expression,substitutio
31、n string):sub(regular expression,substitution string,target string)实例:$awk sub(/test/,mytest);print testfile$awk sub(/test/,mytest);$1;print testfile 第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到 gsub 第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。gsub 函数作用如 sub,但它在整个文档中进行匹配。格式如下:gsub(regular expression,su
32、bstitution string)gsub(regular expression,substitution string,target string)实例:$awk gsub(/test/,mytest);print testfile$awk gsub(/test/,mytest),$1;print testfile 第一个例子在整个文档中匹配 test,匹配的都被替换成 mytest。第二个例子在整个文档的第一个域中匹配,所有匹配的都被替换成 mytest。index 函数返回子字符串第一次被匹配的位置,偏移量从位置 1开始。格式如下:index(string,substring)实例:$
33、awk print index(test,mytest)testfile 实例返回 test 在 mytest 的位置,结果应该是 3。length 函数返回记录的字符数。格式如下:length(string)length 实例:$awk print length(test)$awk print length testfile 第一个实例返回 test 字符串的长度。第二个实例返回 testfile 文件中第条记录的字符数。substr函数返回从位置 1开始的子字符串,如果指定长度超过实际长度,就返回整个字符串。格式如下:substr(string,starting position)substr(string,starting position,length of string)实例:$awk print substr(hello world,7,11)上例截取了 world 子字符串。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1