全部博文(51)
分类:
2010-10-11 15:17:53
AWK教程
绝对经典的awk入门教程,全文转载,未注明出处,还请作者原谅。
0. awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk。
1. awk语言的最基本功能是在文件或字符串中基于指定规则来分解抽取信息,也可以基于指定的规则来输出数据。完整的awk脚本通常用来格式化文本文件中的信息。
2. 三种方式调用awk
1) awk [opion] 'awk_script' input_file1 [input_file2 ...] awk的常用选项option有:
① -F fs : 使用fs作为输入记录的字段分隔符,如果省略该选项,awk使用环境变量IFS的值。
② -f filename : 从文件filename中读取awk_script。
③ -v var=value : 为awk_script设置变量。
2) 将awk_script放入脚本文件并以 #!/bin/awk -f 作为首行,给予该脚本可执行权限,然后在shell下通过键入该脚本的脚本名调用之。
3) 将所有的awk_script插入一个单独脚本文件,然后调用: awk -f awk脚本文件 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_pattern awk_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_file awk
'$3 ~ /^d/ {print "ok"}' input_file
③ &&(与) 和 ||(或) 可以连接两个/regexp/或者布尔表达式,构成混合表达式。!(非)
可以用于布尔表达式或者/regexp/之前。 举例: awk '($1 < 10 ) && ($2 > 10)
{print "ok"}' input_file awk '/^d/ || /x$/ {print "ok"}' input_file
④ 其它表达式用作awk_script,如赋值表达式等 eg: awk '(tot+=$6); END{print "total
points :" tot }' input_file // 分号不能省略 awk 'tot+=$6 {print $0} END{print
"total points :" 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 }'
② 把一个表达式的值赋值给变量。表达式一般是数值表达式,也可以是其它表达式。 数值表达式: num1 operator num2
operator可以是: +(加) -(减) *(乘) /(除) %(取模) ^(求幂)
当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 '{print NR,NF,$0} END {print FILENAME}'
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内有效。
文章出处: