【译】 AWK教程指南 附录B-Actions

  Actions 是由下列指令(statement)所组成:


 1 表达式 ( 函数调用,赋值...)
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
语言中的用法一致,此处仅介绍较为常用或容易混淆的指令的用法。

B.1 程序控制流


  • if 指令

语法:


    if(表达式) 语句1 [else 语句2 ]

范例:


    if( $1 > 25 )
      print "The 1st field is larger than 25"
    else
      print "The 1st field is not larger than 25"

(a)与 C 语言中相同,若 表达式
计算(evaluate)后的值不为 0 或 空字符串,则执行 语句1;否则执行 语句2。

(b)进行逻辑判断的表达式所返回的值有两种,若最后的逻辑值为true,则返回1;否则返回0。

(c)语法中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 将持续进行其后的语句。

  • do-while 指令

语法:


    do 语句 while(表达式)

范例:


    do{
      print "Enter y or n ! "
      getline data
    } while( data !~ /^[YyNn]$/)

(a)上例要求用户从键盘上输入一个字符,若该字符不是Y,
y, N, 或 n则会不停执行该循环,直到读取正确字符为止。

(b)do-while 指令与 while 指令 最大的差异是:do-while
指令会先执行 语句 而后再判断是否应继续执行。所以,无论如何其 语句 部分至少会执行一次。

  • for 语句指令(一)

语法:


    for(variable in  array ) 语句

范例:执行下列命令


    awk ‘
    BEGIN{
      X[1]= 50; X[2]= 60; X["last"]= 70
      for( any in X )
        printf("X[%s] = %d\n", any, X[any] )
    }‘

结果输出:

        

(a)这个 for
指令,专用以查找数组中所有的下标值,并依次使用所指定的变量予以记录。以本例而言,变量 any 将逐次代表 "last"、1及2。

(b)以这个 for 指令,所查找出的下标的值彼此间并无任何次序关系。

(c)第5节中有该指令的使用范例及解说。

  • for 语句指令(二)

语法:


    for(表达式1; 表达式2; 表达式3) 语句

范例:


    for(i=1; i< =10; i++)      
      sum = sum + i

说明:

(a)上列范例用以计算 1 加到 10 的总和。

(b)表达式1  常用于设定该 for 循环的起始条件,如上例中的
i=1

表达式2  常用于设定该循环的停止条件,如上例中的 i
<= 10

表达式3  常用于改变 counter
的值,如上例中的 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 "There is a digital index", index
    }

  上例中若 index 不为数字则执行
continue,故将略过(不执行)其后的指令。

  需留心 continue 与 break 的差异:执行 continue
只是跳过其后未执行的statement,但并未跳出该循环。

  • next 指令

  执行 next 指令时,awk
将跳过位于该指令(next)之后的所有指令(包括其后的所有Pattern { Actions }),接著读取下一行数据,继续从第一个 Pattern
{Actions} 执行起。

范例:


    /^[ \t]*$/  {  print "This is a blank line! Do nothing here !"
             next
           }
    $2 != 0   { print $1, $1/$2 }

  上例中,当 awk 读入的数据行为空白行时(
match /^[ \]*$/ ),除打印消息外,只执行 next,故 awk 将跳过其后的指令,继续读取下一行数据,从头(第一个 Pattern {
Actions })执行起。

  • exit 指令

  执行 exit 指令时,awk将立刻跳出(停止执行)该awk程序。

B.2 AWK中的I/O指令


  • printf 指令

  该指令与 C 语言中的用法相同,可通过该指令控制数据输出时的格式。

语法:


    printf("format", item1, item2,.. )

范例:


    id = "BE-2647";  ave = 89
    printf("ID# : %s Ave Score : %d\n", id, ave)

(a)结果印出:

      

(b)format 部分是由 一般的字串(String Constant) 及
格式控制字符(Formatcontrol letter, 其前会加上一个%字符)所构成。以上式为例,"ID# : " 及 "  Ave Score :
" 为一般字串,%s 及 %d 为格式控制字符。

(c)打印时,一般字串将被原封不动地打印出来。遇到格式控制字符时,则依序把
format后方的 item 转换成所指定的格式后进行打印。

(d)有关的细节,读者可从介绍 C 语言的书籍上得到较完整的介绍。

(e)print 及 printf 两个指令,其后可使用 > 或 >>
将输出到stdout 的数据重定向到其它文件,7.1 节中有完整的范例说明。

  • print 指令

范例:


    id = "BE-267";  ave = 89
    print "ID# :", id, "Ave Score :"ave

(a)结果印出:

      

(b)print 之后可接上字串常数(Constant
String)或变量。它们彼此间可用"," 隔开。

(c)上式中,字串 "ID# :" 与变量 id 之间使用","隔开,打印时两者之间会以自动
OFS(请参考 附录D 內建变量 OFS) 隔开。OFS 的值一般內定为 "一个空格"

(d)上式中,字串 "Ave Score :"
与变量ave之间并未以","隔开,awk会将这两者先当成字串concate在一起(变成"Ave Score :89")后,再予打印

  • getline 指令

语法:



















语法

由何处读取数据

数据读入后置于

getline var < file

所指定的 file

变量 var(var省略时表示置于$0)

| getline var

pipe 变量

变量 var(var省略时表示置于$0)

getline var

见 注一

变量 var(var省略时表示置于$0)

  注一:当Pattern为BEGIN或END时,getline将由stdin读取数据,否则由awk正处理的文件上读取数据。

  getline 一次读取一行数据,若读取成功则return 1;若读取失败则return
-1;若遇到文件结束(EOF)则return 0。

  • close  指令

该指令用以关闭一个打开的 文件 或 pipe (见下例)

范例:


    awk ‘
    BEGIN { print "ID # Salary" > "data.rpt" }

        { print $1 , $2 * $3 | "sort -k 1 > data.rpt" }

    END  { close( "data.rpt" )
          close( "sort -k 1 > data.rpt" )
          print " There are", NR, "records processed."
        } ‘

说明:

(a)上例中, 一开始执行 print "ID #   Salary"
> "data.rpt" 指令来输出一行抬头。它使用 I/O Redirection ( > )将数据转输出到data.rpt,此时文件
data.rpt 是处于 Open 状态。

(b)指令 print $1, $2 * $3 不停的将输出的数据送往
pipe(|),awk在程序将结束时才会调用 shell 使用指令 "sort -k 1 > data.rpt" 来处理 pipe
中的数据;并未立即执行,这点与 Unix 中pipe的用法不尽相同。

(c)最后希望在文件 data.rpt 的末尾处加上一行 "There
are....."。但此时,Shell尚未执行 "sort -k 1 > data.rpt",故各行数据排序后的 ID 及 Salary
等数据尚未写入data.rpt。所以得命令 awk 提前先通知 Shell 执行命令 "sort -k 1 > data.rpt" 来处理 pipe
中的数据。awk中这个动作称为 close pipe,通过执行 close ( "shell command" )来完成。需留心 close( )指令中的
shell command 需与"|"后方的 shell command
完全相同(一字不差),较佳的方法是先为该字串定义一个简短的变量,程序中再以此变量代替该shell command。

(d)为什么执行 close("data.rpt")?因为 sort
完后的资料也将写到data.rpt,而该文件正为awk所打开使用(write)中,故awk程序中应先关闭data.rpt,以免造成因两个 进程
同时打开一个文件进行输出(write)所产生的错误。

  • system 指令

  该指令用以执行 Shell上的 command。

范例:


    DataFile = "invent.rpt"
    system( "rm " DataFile )

说明:

(a)system("字符串")指令接受一个字符串当成Shell的命令。上例中,使用一个字串常数"rm "
连接(concate)一个变量 DataFile 形成要求 Shell 执行的命令。Shell 实际执行的命令为 "rm
invent.rpt"。

  • "|" pipe指令

  "|" 配合 awk 输出指令,可把 output 到 stdout
的数据继续转送给Shell 上的某一命令当成input的数据。"|"  配合 awk getline 指令, 可调用 Shell 执行某一命令,再以
awk 的 getline 指令将该命令的所产生的数据读进 awk 程序中。

范例:


    { print $1, $2 * $3  | "sort -k 1 > result" }
    "date" | getline Date_data

  读者请参考7.2
节,其中有完整的范例说明。

B.3 awk释放所占内存的指令


  awk 程序中常使用数组(Array)来保存大量数据,delete
指令便是用来释放数组中的元素所占用的内存空间。

范例:


    for( any in X_arr )
      delete X_arr[any]

  读者请留心,delete
指令一次只能释放数组中的一个元素。

B.4 awk 中的数学运算符(Arithmetic Operators)


  +(加)、  -(減)、  *(乘)、  /(除)、  %(求余数)、  ^(指数) 与
C 语言中用法相同。

B.5 awk 中的赋值运算符(Assignment Operators)


=、  +=、  -=、  *=、  /=、  %=、  ^=

x += 5 的意思为 x = x + 5,其余类推。

B.6 awk 中的条件运算符(Conditional  Operator)


语法:


    判断条件 ? value1 : value2

  若 判断条件 成立(true) 则返回
value1,否则返回 value2。

B.7 awk 中的逻辑运算符(Logical Operators)


&&( and )、  ||(or)、  !(not)

Extended Regular Expression 中使用 "|" 表示 or
请勿混淆。

B.8 awk 中的关系运算符(Relational Operators)

>、  >=、  <、  <=、  ==、  !=、  ~、  !~

B.9 awk 中其它的运算符


+(正号)、  -(负号)、  ++(Increment Operator)、  -
-(Decrement Operator)

B.10 awk 中各运算符的运算级


  按优先级从高到低排列:



































$

字段运算元,例如:

i=3; $i表示第3个字段

^ 指数运算
+, -,
!
正、负号,及逻辑上的 非
* ,/
,%
乘,除,余数
+
,-
加,減
>,
>  =,< , < =, ==, !=
关系运算符
~,
!~
match,
not match
&& 逻辑上的
and
|| 逻辑上的
or
?
:
条件运算符
= , +=,
-=,*=, /=, %=, ^=
赋值运算符

【译】 AWK教程指南 附录B-Actions,布布扣,bubuko.com

时间: 2024-10-11 15:28:01

【译】 AWK教程指南 附录B-Actions的相关文章

【译】 AWK教程指南 附录A-Patterns

awk 通过判断 Pattern 的值来决定是否执行其后所对应的Actions.这里列出几种常见的Pattern: A.1 BEGIN BEGIN 为 awk 的保留字,是一种特殊的 Pattern. BEGIN 成立(其值为true)的时机是: "awk 程序一开始执行,尚未读取任何数据之前." 所以在 BEGIN { Actions } 语法中,其 Actions 部份仅于程序一开始执行时被执行一次.当 awk 从数据文件读入数据行后, BEGIN 便不再成立,故不论有多少数据行,

【译】 AWK教程指南 附录E-正则表达式

为什么要使用正则表达式 UNIX 中提供了许多 指令 和 tools,它们具有在文件中 查找(Search)字串或替换(Replace)字串 的功能.像 grep, vi , sed, awk,... 不论是查找字串或替换字串,都得先告诉这些指令所要查找(被替换)的字串为何.若未能预先明确知道所要查找(被替换)的字串为何,只知该字串存在的范围或特征时,例如: (一)查找 "T0.c", "T1.c", "T2.c".... "T9.c&

【译】 AWK教程指南 附录D-AWK的内置变量

因内置变量的个数不多,此处按其相关性分类说明,并未按其字母顺序排列. ARGC ARGC表示命令行上除了选项 -F, -v, -f 及其所对应的参数之外的所有参数的个数.若将"awk程序"直接写在命令列上,则 ARGC 亦不将该"程序部分"列入计算. ARGV ARGV数组用以记录命令列上的参数. 例:执行下列命令 $ awk -F\t -v a=8 -f prg.awk file1.dat file2.dat 或 $ awk -F\t -v a=8 '{ prin

【译】 AWK教程指南 4通过文本内容和对比选择指定的记录

Pattern { Action }为awk中最主要的语法.若某Pattern的值为真则执行它后面的 Action. awk中常使用"关系表达式" (Relational Expression)来当成 Pattern. awk 中除了>, <, ==, != ,...等关系运算符( Relational Operators )外,另外提供 ~(match),!~(Not Match) 二个关系运算符.利用这两个运算符,可判断某字符串是否包含能匹配所指定正则表达式的子字符串.

【译】 AWK教程指南 3计算并打印文件中指定的字段数据

awk 处理数据时,它会自动从数据文件中一次读取一条记录,并会将该记录切分成一个个的字段:程序中可使用 $1, $2,... 直接取得各个字段的内容.这个特色让使用者易于用 awk 编写 reformatter 来改变数据格式. 范例:以数据文件 emp.dat 为例,计算每人应发工资并打印报表. 分析:awk 会自行一次读入一条记录,故程序中仅需告诉 awk 如何处理所读入的数据行. 执行如下命令:($ 表UNIX命令行上的提示符)  $ awk '{ print $2, $3 * $4 }'

【译】 AWK教程指南 2概述

2.1 为什么用AWK 由于awk具有上述特色,在问题处理的过程中,可轻易使用awk来撰写一些小工具:这些小工具并非用来解决整个大问题,它们只扮演解决个别问题过程的某些角色,可通过Shell所提供的pipe将数据按需要传送给不同的小工具进行处理,以解决整个大问题.这种解题方式,使得这些小工具可因不同需求而被重复组合及使用(reuse):也可通过这种方式来先行测试大程序原型的可行性与正确性,将来若需要较高的执行速度时再用C语言来改写.这是awk最常被应用之处.若能常常如此处理问题,读者可以以更高的

【译】 AWK教程指南 1前言

前面的话: 这几天写了一个程序,在同一个目录里生成了很多文件,需要统计其中部分文件的总大小,发现经常用到的ls.du等命令都无济于事,我甚至都想到了最笨的方法,写一个脚本:mkdir一个新目录,把要统计总大小的文件mv过去,然后du或者ls -lh新目录.诚然,这个办法又笨又不精确,于是求助万能的网络,找到的都是同一篇用了3个很长的循环来统计的脚本,还是自己先苦读"经书"吧.鸟哥的书第十二章就有现成的示例,就用到了马上要出场的awk工具,用法如下(统计目录下所有tmp*文件的总大小,以

【译】 AWK教程指南 5AWK中的数组

awk程序中允许使用字符串当做数组的下标(index).利用这个特色十分有助于资料统计工作.(使用字符串当下标的数组称为Associative Array) 首先建立一个数据文件,并取名为 reg.dat.此为一学生注册的资料文件:第一栏为学生姓名,其后为该生所修课程. awk中数组的特性 1. 使用字符串当数组的下标(index). 2. 使用数组前不须声明数组名及其大小. 例如:希望用数组来记录 reg.dat 中各门课程的修课人数.这情况,有两项信息必须储存: (a) 课程名称,如: "O

【译】 AWK教程指南 7AWK应用实例

本节将示范一个统计上班到达时间及迟到次数的程序. 这程序每日被执行时将读入两个数据文件: * 员工当日到班时间的数据文件 ( 如下列的 arr.dat ) * 存放员工当月迟到累计次数的文件 当程序执行执完毕后将更新第二个数据文件的数据(迟到次数),并打印当日的报表.这程序将分成下列数小节逐步完成,其大纲如下: 7.1 在到班资料文件 arr.dat 之前增加一行抬头"ID Number Arrvial Time",并产生报表输出到文件today_rpt1 中. <在awk中如何