awk使用 第十二部分 awk主题函数Actions的指令语法

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 )    
    ? :     (条件运算符)
    = , +=, -=,*=, /=, %=, ^= (赋值运算符)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值