awk的Actions一般由下列指令(statement)所组成:
1、 表达式 ( function calls, assignments..)
2、print 表达式列表
3、printf( 格式化字符串, 表达式列表)
4、if( 表达式 ) 语句 [else 语句]
5、while( 表达式 ) 语句
6、do 语句 while( 表达式)
7、for( 表达式; 表达式; 表达式) 语句
8、for( variable in array) 语句
9、delete
10、break
11、continue
12、next
13、exit [表达式]
14、语句
在awk 中大部分指令和C 语言中的用法一致,这里仅介绍比较常用或容易混淆的指令的用法。
一、流程控制指令
if 指令
语法:if (表达式) 语句1 [else 语句2 ]
范例:
[root@myfreelinux pub]# cat inte
123
324
[root@myfreelinux pub]# cat action.awk
#!/bin/awk -f
{
if($0>100)
print “the number is :” $0
else
print “the number add 100 is :” $0+100
}
[root@myfreelinux pub]# awk -f action.awk inte
上例中if语句的用法和C 语言中相同,1、如果表达式计算(evaluate)的值小于100, 则执行 print “the number is :” $0;否则执行print “the number add 100 is :” $0+100
2、进行逻辑判断的表达式所返回的值有两种,如果逻辑值为true,则返回1,否则返回0。
3、语法中else 语句2以[ ] 前后括住表示该部分根据需要加入或省略。
while 指令
语法:while( 表达式 ) 语句
范例:
while( match(buffer,/[0-9]+/.c/ ) )
{ print “Find :” substr( buffer,RSTART,RLENGTH)
buff = substr( buffer,RSTART + RLENGTH) }
上例找出buffer中所有能匹配/[0-9]+.c/(数字之后接上 “.c”的所有子字符串)。while以函数match( )所返回的值做为判断条件。如果buffer中含有匹配指定条件的子字符串(match成功),则match()函数返回1,while 将持续进行其后的语句,while执行的条件是只要条件为真就会执行,知道判断条件为假停止执行判断语句。
do-while 指令
语法:
do 语句 while(表达式)
范例:
do{ print “Enter y or n ! ” getline data }
while( data !~ /^[YyNn]$/)
1、上例要求用户从键盘上输入一个字符,如果该字符不是Y,y,N或n,则会不停执行该循环,直到读取正确字符为YyNn为止。
2、do-while 指令与while 指令最大的差异是:do-while指令会先执行一次语句,然后再判断是否应继续执行。 所以,无论条件是否成立,语句至少会执行一次。
for循环语句
语法一:for(variable in array ) statement
范例:执行一下awk语句:
[root@myfreelinux pub]# awk ‘BEGIN{a["one"]=1;a[2]=2;a["three"]=3;for(one_array in a) printf(“a[%s]=%d/n”,one_array,a[one_array]);}’
a[three]=3
a[2]=2
a[one]=1
1、for循环可以查找数组中所有的下标值,并依次使用所指定的变量记录这些下标值,以本例而言,变量one_array将依次代表 “three”,“2”,“one”
2、for循环指令查找出的下标值之间没有任何次续关系。
语法二 :
for(expression1; expression2; expression3) statement
范例:for(i=1; i<=10; i++) sum=sum + i
说明:1、上例用来计算1加到10的总和。
2、expression1常用于设定该for 循环的起始条件,如 i=1;expression2 用于设定该循环的停止条件,比如i<=10;expression3 常用于改变expression1的值,直到使表达式2满足条件跳出循环,如i++。
break指令
break指令用以强迫中断(跳离) for,while,do-while 等循环。
范例:
while(getline < “datafile” > 0 )
{ if( $1 == 0 ) break
else print $2/$1 }
上例中,awk 不断地从数据文件datafile中读取资料,当$1等于0时,停止该执行循环。
continue 指令
循环中的运行一部分是,执行continue指令来跳过循环中尚未执行的语句。
范例:
for( index in X_array)
{ if( index !~ /[0-9]+/ )
continue
print “Juest print the digital index”, index }
上例中如果index不是数字则执行continue,即跳过后面的print语句。continue和break 是不同的:continue只是跳过后面没有执行的语句,但不会离开该循环。
next 指令
执行next指令时,awk会跳过next指令之后的所有语句,包括next之后的所有Pattern { Actions },接着读取下一笔数据行,继续从第一个 Pattern {Actions} 执行起。
范例:
[root@myfreelinux pub]# cat integer
222 111
333 111
444 111
[root@myfreelinux pub]# cat action.awk
#!/bin/awk -f
{
if(/^[ /t]*$/)
{
print “this is a blank line,nothing here!”;
next;
}
$2!=0
{
printf(“$1 is %d,$2 is %d,$2/$1 is %d/n”,$1,$2,$1/$2);
}
}
[root@myfreelinux pub]# awk -f action.awk integer
$1 is 222,$2 is 111,$2/$1 is 2
$1 is 333,$2 is 111,$2/$1 is 3
this is a blank line,nothing here!
$1 is 444,$2 is 111,$2/$1 is 4
说明:awk 读入的数据行为空白行时( match /^[ /]*$/ ),除打印消息外只执行next,即awk将跳过其后的指令,继续读取下一行数据,从头开始并再次执行if(/^[ /t]*$/)语句
exit 指令
执行exit 指令时,awk将立刻跳离(停止执行)awk程序。
awk 中的I/O指令
printf 指令
printf指令与C 语言中的用法相同,使用这个指令可以控制数据输出时的格式。
语法:printf(“format”, item1, item2,.. )
范例: printf(“$1 is %d,$2 is %d,$2/$1 is %d/n”,$1,$2,$1/$2);
1、format 部分是由一般的字串(String Constant) 和格式控制字符(Formatcontrol letter,其前会加上一个%字符)所构成。%s 和%d是最常用的格式控制字符.
2、一般字串将被原封不动地打印出来,遇到格式控制字符时,依序把format后方的item转换成所指定的格式后进行打印。
3、print和printf后民可使用> 或>>将输出到stdout 的数据重定向到其它文件,
print 指令
范例: print “Juest print the digital index”, index
1、这个例子是上面打印数组下标的例子
2、print 之后可接上字串常数(Constant String)或变量,用”,” 隔开。
getline 指令
getline var < file,file为数据文件,变量var是数据存放的变量,var省略时,数据存放到$0。
getline var pipe 变量 ,var省略时,数据存放到$0中。
getline 一次读取一行资料,若读取成功则return 1,若读取失败则return -1, 若遇到文件结束(EOF), 则return 0
close 指令 该指令用以关闭一个打开的文件,或pipe
范例:[root@myfreelinux pub]# cat reformat3.awk
#!/bin/bash
awk ‘BEGIN{
FS=”[ /t:]+”;
“date”|getline;
print “Today is”,$2,$3 > “today_result3″;
close(“today_result3″);
}
{
arrival=HM_TO_M($2,$3);
printf(“%s/t/t%s:%s %s/n”,$1,$2,$3,arrival>”480″?”*”:“ ”)|“sort -k 1 >> today_result3″;
total+=arrival;
}
END{
close(“sort -k 1 >> today_result3″);
printf(“Average arrival time: %d:%d/n”,total/NR/60, total/NR%60) >> “today_result3″;
close(“today_result3″);
}
function HM_TO_M(hour,min){ return hour*60 + min }’ $*
说明:1、上例中,一开始执行print “Today is”,$2,$3 > “today_result3″;指令输出今天的月份和日期,使用了I/O 的数据重定向( > )将数据转输出到today_result3,所以today_result3处于打开状态
2、printf(“%s/t/t%s:%s %s/n”,$1,$2,$3,arrival>”480″?”*”:” “)不停的将输出的资料送往pipe(|),awk 在程序在结束时会呼叫shell,使用指令“sort -k 1 >> today_result3″来处理管道中的数据。而不是将数据输出到管道的时候就开始排序,这一点和Unix 中pipe 的用法不完全相同。
3、最后希望在文件的末尾加上“Average arrival time”,但此时,Shell还没有执行“sort -k 1 >> today_result3″,所以数据行排序结果还没有写入today_result3中,或者可以认为是today_result3处于打开状态,所以awk应该提前通知Shell执行命令“sort -k 1 >> today_result3″,来处理pipe中的资料。awk 中这个动作称为close pipe,是由执行close ( “shell command” )来完成。需要注意的是close( )指令中的shell command 需与”|”后方的shell command 完全相同(一字不差),比较好的方法是先将该字串定义一个简短的变量,程序中再以此变量代替该shell command
4、为什么执行close(“today_result3″)?这是因为sort完后的资料也将写到today_result3中,这个文件正为awk所打开使用(write)中,所以awk程序中要先关闭today_result3,以免造成因二个进程同时打开一个文件进行输出(write)产生的错误。
5、close使用的时机是:在第二次写入前,应该关闭前一次写入时打开的文件,close的时候一定于上次打开文件是的打开方式相同。
system 指令
该指令用来执行Shell上的command。
比如:
path=/etc/local/apache2
system( “rm -rf” path)
说明:
system(“字符串”)指令接受一个字符串当成Shell 的命令,上例中,使用一个字串常数”rm -rf” 连接(concate)一个变量path,形成Shell 执行命令的格式,Shell实际执行的命令是“rm -rf /etc/local/apache2”。
“|” pipe指令
“|” 配合awk 输出指令,可以把输出到标准输出即屏幕的资料继续转送给管道后面,作为管道后面的标准输入。”|”配合awk的getline指令,可呼叫Shell执行某一命令,再将getline指令所得到的资料读进awk 程序中。
例如:
“date”|getline;
print “Today is”,$2,$3 > “today_result3″;可参考6.2程序例子部分。
awk 释放所占用内存的指令
awk程序中常使用数组(Array)来存储大量数据,delete 指令可以用来释放数组所占用的内存空间。
比如:for( any in X_arr ) delete X_arr[any] ,需要注意的是:delete 指令一次只能释放数组中的一个元素.。
awk 中的数学运算符(Arithmetic Operators)
+(加), -(減), *(乘), /(除), %(求余数), ^(指数) 与C 语言中用法相同
awk 中的赋值运算符(Assignment Operators)
=, +=, -=, *= , /=, %=, ^=
x += 5 的意思是x = x + 5, 其余类推,其实和C语言中的用法相同
awk 中的条件运算符(Conditional Operator)
语法: 判断条件? value1 :value2
如果判断条件成立(true) 则返回value1,否则返回value2,这个语句也就是C语言中的三元运算符(?:)
awk 中的逻辑运算符(Logical Operators)
&&( and ), ||(or), !(not),正则表达式中使用”|” 表示||,比较容易混淆
awk 中的关系运算符(Relational Operators)
>, >=, <, < =, ==, !=, ~, !~
awk 中其它的运算符
+(正号),-(负号), ++(自加),–(自减)
awk 中各运算符的运算级
按优先高低排列:
$(栏位运算元,例如:i=3; $i表示第3栏);
^(指数运算) ;
+ ,- ,! (正,负号,及逻辑上的 not);
* ,/ ,% (乘,除,余数) ;
+ ,- (加,減) ;
>, > =,< , < =, ==, != (关系运算符);
~, !~ (match, not match) ;
&& (逻辑and)
|| (逻辑上的 or )
? : (条件运算符)
= , +=, -=,*=, /=, %=, ^= (赋值运算符)