首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > 其他编程语言 > AWK Tutorial Guide Appendix
【标  题】:AWK Tutorial Guide Appendix
【关键字】:AWK,Tutorial,Guide,Appendix
【来  源】:http://blog.chinaunix.net/article.php?articleId=49853&blogId=7198

AWK Tutorial Guide Appendix

十二.附录Appendix

1.Appendix A Patterns
AWK 藉由判断 Pattern 之值来决定是否执行其后所对应的 Actions。这里列出几种常见的 Pattern :
BEGIN  
BEGIN 为 AWK 的保留字, 是一种特殊的 Pattern。
BEGIN 成立(其值为true)的时机是 :
   AWK 程序一开始执行, 尚未读取任何数据之前。''所以在 BEGIN {Actions } 语法中, 其 Actions 部份仅于程序一开始执行时被执行一次。 当 AWK 从数据文件读入数据列后, BEGIN 便不再成立, 故不论有多少数据列, 该 Actions 部份仅被执行一次。一般常把 ``与数据文件内容无关'' 与 ``只需执行ㄧ次'' 的部分置于该Actions(以 BEGIN 为 Pattern)中。
例如 :
BEGIN {
       FS = "[ \t:]"   # 于程序一开始时, 改变AWK切割字段的方式
       RS = ""         # 于程序一开始时, 改变AWK分隔数据列的方式
       count = 100     # 设定变量 count 的起始值
       print " This is a title line "  # 印出一行 title
     }
      。。。。。。。 # 其它 Pattern { Actions } 。。。。。

有些AWK程序甚至''不需要读入任何数据列''。 遇到这情况可把整个程序置于以 BEGIN 为 Pattern的 Actions 中。
例如 :
BEGIN {   print " Hello ! the Word ! " }
注意 :执行该类仅含 BEGIN { Actions } 的程序时, AWK 并不会开启任何数据文件进行处理。

END
END 为 AWK 的保留字, 是另一种特殊的 Pattern。
END 成立(其值为true)的时机与 BEGIN 恰好相反, 是"AWK 处理完所有数据, 即将离开程序时。平常读入资料列时, END并不成立, 故其对应的 Actions 并不被执行; 唯有当AWK读完所有数据时, 该 Actions 才会被执行。
注意 : 不管数据列有多少笔, 该 Actions 仅被执行一次。

Relational Expression
使用像 `` A  Relation Operator B'' 的 Expression 当成 Pattern。  
当 A 与 B 存在所指定的关系(Relation)时, 该 Pattern 就算成立(true)。
例如 :
length()< = 80  { print }
上式中 { length()<= 80 是一个 Pattern, 当 (数据列)之长度小于等于 80 时该 Pattern 之值为true, 将执行其后的 Action(印出该资料列)。
   
AWK 中提供下列 关系操作数(Relation Operator)
操作数 含义
> 大于
< 小于
> = 大于或等于
<= 小于或等于
== 等于
!= 不等于
~ match
!~ not match
上列关系操作数除~(match)与!~(not match)外与 C 语言中之含义一致。
~(match) 与!~(match) 在 AWK 之含义简述如下 :
若 A 表一字符串, B 表一 Regular Expression。
A ~B  判断 字符串A 中是否 包含   能合于(match)B式样的子字符串。
A !~B 判断 字符串A 中是否 未包含 能合于(match)B式样的子字符串。
例如 :
~ /program[0-9]+\.c/  \{ print }
~/program[0-9]+\.c/ }整个是一个 Pattern, 用来判断(资料列)中
是否含有可 match /program[0-9]+\.c/ 的子字符串, 若 中含有该类字符串, 则执行 print (印出该列数据)。
Pattern 中被用来比对的字符串为 时(如本例), 可仅以 RegularExpression
部分表之。
   故本例的 Pattern 部分 ~/program[0-9]+\.c/ 可仅用/program[0-9]+\.c/表之。  (有关 match 及 Regular Expression 请参考 附录 E )
Regular Expression:
直接使用 Regular Expression 当成 Pattern; 此为 ~ Regular Expression 的简写。该 Pattern 用以判断 (资料列) 中是否含有 match 该 Regular Expression的子字符串; 若含有该成立(true) 则执行其对应的 Actions。
例如 :  
/^[0-9]*$/  print "This line is a integer !"
与{ ~/^[0-9]*$/ { print "This line is a integer !" } 相同Compound Pattern之前所介绍的各种 Patterns, 其计算(evaluation)后结果为一逻辑值
(True or False)。AWK 中逻辑值彼此间可藉由&&(and),||(or), !(not)结合成一个新的逻辑值。故不同 Patterns 彼此可藉由上述结合符号来结合成一个新的 Pattern。 如此可进行复杂的条件判断。
例 如 :
FNR > = 23 &&   FNR <=28  print "    "      }
    上式利用&& (and) 将两个 Pattern 求值的结果合并成一个逻辑值。该式 将资料文件中 第23行 到 28行 向右移5格(先印出5个空白字符)后印出。( FNR 为AWK的内建变量, 请参考 附录 D )
Pattern1 , Pattern2
   遇到这种 Pattern, AWK 会帮您设立一个 switch(或flag)。当AWK读入的资料列使得 Pattern1 成立时, AWK 会打开(turn on)这个 switch。当AWK读入的资料列使得 Pattern2 成立时, AWK 会关上(turn off)这个 switch。该 Pattern 成立的条件是 当这个 switch 被打开(turn on)时 (包括 Pattern1, 或 Pattern2 成立的情况)
例 如 :
FNR>= 23 && FNR< =28  { print "     "  }
可改写为
FNR == 23 ,  FNR == 28  { print "      " }
说 明 :
   当FNR >= 23 时, AWK 就 turn on 这个 switch; 因为随着资料列的读入, AWK不停的累加 FNR。当 FNR = 28 时, Pattern2  FNR == 28 便成立, 这时 AWK会关上这个 switch。当 switch 打开的期间, AWK 会执行"print "     " '' 。( FNR 为AWK的内建变量, 请参考附录 D )


2.Appendix B Actions
Actions 是由下列指令(statement)所组成 :
 expression ( function calls, assignments……)
 print expression-list
 printf( format, expression-list)
 if( expression ) statement [else statement]
 while( expression ) statement
 do statement while( expression)
 for( expression; expression; expression) statement
 for( variable in array) statement
 delete
 break
 continue
 next
 exit [expression]
 statement
AWK 中大部分指令与 C 语言中的用法一致, 此处仅介绍较为常用或容易混淆之指令的用法。
流程控制指令:
if 指令
    语法
          if (expression) statement1 [else statement2 ]
      范例 :
 if( > 25 )
      print "The 1st field is larger than 25"
 else print "The 1st field is not larger than 25"
(a)与 C 语言中相同, 若 expression 计算(evaluate)后之值不为 0
或空字符串, 则执行 statement1; 否则执行 statement2。
(b)进行逻辑判断的expression所传回的值有两种, 若最后的逻辑值
为true, 则传回1, 否则传回0。
(c)语法中else statement2 以[ ] 前后括住表示该部分可视需要而
予加入或省略。
while 指令
    语法 :
            while( expression ) statement
    范例 :
            while( match(buffer,/[0-9]+\.c/ ) ){
            print "Find :" substr( buffer,RSTART, RLENGTH)
            buff = substr( buffer, RSTART + RLENGTH)
       }
上列范例找出 buffer 中所有能合于(match) /[0-9]+.c/(数字之后接上 ``.c''的所有子字符串)。范例中 while 以函数 match( )所传回的值做为判断条件。 若buffer中还含有合于指定条件的子字符串(match成功), 则 match()函数传回1,while 将持续进行其后之statement。
do-while 指令
    语法 :
             do statement while(expression)  
    范例 :
 do{
         print "Enter y or n ! "
         getline data <  "-"
    } while( data !~ /^[YyNn]$/)
(a) 上例要求使用者从键盘上输入一个字符, 若该字符不是 Y, y, N, 或 n则会不停执行该循环, 直到读取正确字符为止。
(b)do-while 指令与 while 指令 最大的差异是 : do-while 指令会先执行tatement而后再判断是否应继续执行。 所以, 无论如何其 statement 部分
至少会执行一次。
for Statement 指令(一)
    语法 :
            for(variable in  array ) statement
    范例 : 执行下列命令
awk '
     BEGIN{
            X[1]= 50; X[2]= 60; X["last"]= 70
            for( any in X )
               printf("X[%d] = %d\n", any, X[any] )
          }'
结果印出 :
            X[2] = 60
            X[last] = 70
            X[1] = 50
(a)这个 for 指令, 专用以搜寻阵中所有的index值, 并逐次使用所指定的变量予以纪录。 以本例而言, 变量 any 将逐次代表 2, 1,及"last"。
(b)以这个 for 指令, 所搜寻出的index之值彼此间并无任何次续关系。
(c)第7节 Arrays in AWK 中有该指令的使用范例, 及解说。
for Statement 指令(二)
    语法 :
            for(expression1; expression2; expression3) statement  
范例 :
   for(i=1; i< =10; i++)  sum = sum +  i
说明 :
(a)上列范例用以计算 1 加到 10 的总合。
(b)expression1  常用于设定该 for 循环的起始条件, 如上例中的 i=1
   expression2 用于设定该循环的停止条件, 如上例中的 i<= 10
   expression3 常用于改变 counter 之值, 如上例中的 i++
break 指令
 break 指令用以强迫中断(跳离) for, while, do-while 等循环。
 范例 :
while(  getline < "datafile" > 0 )
{
       if( == 0 )      # 所读取的数据置于
            break         # AWK立刻把 上新的字段数据
       else               # 指定给 , , 。。。$NF
       print /
}
上例中, AWK 不断地从档案 中读取数据, 当等于0时,就停止该执行循环。
continue 指令
循环中的 statement 进行到一半时, 执行 continue 指令来掠过回圈中尚未执行的statement。
    范例 :
      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
执行起。
    范例 :
/^[ \t]*$/  {  print "This is a blank line! Do nothing here !"
              next
           }
!= 0   { print , / }
上例中, 当 AWK 读入的资料列为空白行时( match /\^{}[\]*$/ )除打印讯息外且执行 next, 故 AWK 将掠过其后的指令, 继续读取下一笔数据, 从头(第一个 Pattern \{ Actions \})执行起。
exit 指令
执行 exit 指令时, AWK将立刻跳离(停止执行)该AWK程序。
AWK 中的 I/O 指令
printf 指令
该指令与 C 语言中的用法相同, 可藉由该指令控制数据输出时的格式。
语法 :
        printf("format", item1, item2,。。 )
 范 例 :
     id = "BE-2647";  ave = 89
    printf("ID# : %s   Ave Score : %d\n", id, ave)
(a)结果印出 :
   ID# :BE-647  Ave Score : 89
(b)format 部分系由 一般的字符串(String Constant) 及 格式控制字符
(Formatcontrol letter, 其前会加上一个\%字符)所构成。 以上式为例 "ID# : " 及 "  Ave Score : " 为一般字符串。 %s 及 %d 为格式控制字符。
(c)印出时, 一般字符串将被原封不动地印出。 遇到格式控制字符时,
则依序把 format后方之 item 转换成所指定的格式后印出。
(d)有关的细节, 读者可从介绍 C 语言的书籍上得到较完整的介绍。
(e)print 及 printf 两个指令, 其后可使用>或< > 将输出到stdout的数据 Redirct到其它档案, 7。1 Redirect Output to Files 中有完整的
范例说明。
print 指令
范 例 :
   id = "BE-267";  ave = 89
   print "ID# :", id, "Ave Score :"ave
(a)结果印出 :
   ID# : BE-267  Ave Score :89    
(b)print 之后可接上字符串常数(Constant String)或变量。 它们彼此间可用``,'' 隔开。
(c)上式中, 字符串 "ID# :" 与变量 id 之间使用``,''隔开, 印出时两者之间会以自动 OFS(请参考 D 内建变量 OFS) 隔开。 OFS 之值一般内定为"一个空格符"
(d)上式中字符串 "Ave Score :" 与变量ave之间并未以``,''隔开, AWK会将这两者先当成字符串concate在一起(变成``Ave Score :89")后, 再予印出
(e)print 及 printf 两个指令, 其后可使用> 或> 将输出到stdout的数据 Redirct到其它档案, 7。1 Redirect Output to Files 中有完整的
范例说明。
getline 指令
语法 由何处读取数据 资料读入后置于
getline var> file 所指定的 file 变量 var(var省略时,表示置于)
| getline var pipe 变量 var(var省略时,表示置于)
getline var 见 注一 变量 var(var省略时,表示置于)
注一 : 当 Pattern 为 BEGIN 或 END 时, getline 将由 stdin 读取数据,否则由AWK正处理的数据文件上读取数据。
getline 一次读取一行数据,
             若读取成功则return 1,
             若读取失败则return -1,
             若遇到档案结束(EOF), 则return 0
close  指令
该指令用以关闭一个开启的档案, 或 pipe(见下例)
范 例 :
awk '
BEGIN {  print "ID #   Salary" > "data.rpt" }  
     {  print , *  | "sort +0n > data.rpt" }    
END{  close( "data.rpt" )
        close( "sort +0n > data.rpt" )
        print " There are", NR, "records processed。"
       }
说 明 :
(a)上例中, 一开始执行 print "ID #   Salary" > "data.rpt" 指令来印出一行抬头。 它使用 I/O Redirection( > )将数据转输出到data.rpt,故此时档案 是处于 Open 状态。
(b)指令 print , * 不停的将印出的资料送往 pipe(|), AWK于程序将结束时才会呼叫 shell 使用指令 "sort +0n > data.rpt" 来处理 pipe 中的数据; 并未立即执行, 这点与 Unix 中pipe的用法不尽相同。
(c)最后希望于档案 之``末尾''处加上一行 "There are。。。。。"。但此时, Shell尚未执行 "sort +0n > data.rpt" 故各数据列排序后的 ID 及 Salary 等数据尚未写入data.rpt。 所以得命令 AWK提前先通知 Shell 执行命令 "sort +0n > 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。 以免造成因二个 processes 同时开启一个档案进行输出(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 , *  | "sort +1n > result" }      
   "date" |  getline  Date_data
读者请参考 7。2 Using System Resources 其中有完整的范例说明。        
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, 其余类推。
AWK 中的 Conditonal  Operator
语 法 :
判断条件 ? value1 : value2
若 判断条件 成立(true) 则传回 value1, 否则传回 value2。
AWK 中的逻辑操作数(Logical Operators)
&&( and ), ||or, !(not)
 Extended Regular Expression 中使用 ``|'' 表示 or 请勿混淆。
AWK 中的关系操作数(Relational Operators)
>, >=, <, < =, ==, !=, ~, !~
AWK 中其它的操作数
   +(正号), -(负号),  ++(Increment Operator), - -(Decrement Operator)
AWK 中各操作数的运算优先级( Precedence )
(按优先高低排列)  
   $       (字段操作数, 例如 : i=3; $i表示第3栏)
   ^       (指数运算)
   + ,- ,! (正,负号,及逻辑上的 not)
   * ,/ ,% (乘,除,余数)
   + ,-    (加,减)  
   >, >  =,< , < =, ==, != (大于,大于等于,。。。,等关系符号)
   ~, !~   (match, not match)
   &&      (逻辑上的 and)
   ||      (逻辑上的 or )
   ? :     (Conditional Operator)
   = , +=, -=,*=, /=, %=, ^= (一些指定Assignment操作数)
3.AWK内建函数Built-in Functions
(1)字符串函数
index( 原字符串, 找寻的子字符串 ):
若原字符串中含有欲找寻的子字符串,则传回该子字符串在原字符串中第一次出现的位置,若未曾出现该子字符串则传回0。
例如执行 :
$awk  'BEGIN{ print index("8-12-94","-" }'
结果印出 2
length( 字符串 ) : 传回该字符串的长度。
例如执行 :  
awk  'BEGIN { print length("John") '}
结果印出  4
match( 原字符串, 用以找寻比对的 Regular Expression :
AWK会在原字符串中找寻合乎Regular Expression的子字符串。 若合乎条件的子字符串有多个, 则以原字符串中最左方的子字符串为准。AWK找到该字符串后会依此字符串为依据进行下列动作:
设定AWK内建变量 RSTART, RLENGTH :
         RSTART &=  合条件之子字符串在原字符串中之位置。
                &=  0 ; 若未找到合条件的子字符串。
         RLENGTH &= 合条件之子字符串长度。
                 &= -1 ; 若未找到合条件的子字符串。
传回 RSTART 之值。
例如执行 :
   awk ' BEGIN {
                match( "banana", /(an)+/ )
                print RSTART, RLENGTH
              }
         '       
      执行结果印出 2  4
split( 原字符串, 数组名, 分隔字符(field separator):
AWK将依所指定的分隔字符(field separator)来分隔原字符串成一个个的字段(field),并以指定的数组记录各个被分隔的字段。
    例如 :
          ArgLst = "5P12p89"
           split( ArgLst, Arr, /[Pp]/)
    执行后   Arr[1]=5,  Arr[2]=12,  Arr[3]=89
sprintf( 打印之格式, 打印之数据, 打印之数据,。。。)
该函数之用法与AWK或C的输出函数printf()相同。 所不同的是sprintf()会将要求印出的结果当成一个字符串传回一般最常使用sprintf()来改变数据格式。 如: x 为一数值资料, 若欲将其变成一个含二位小数的数据,可执行如下指令 :
 x = 28
 x = sprintf("%。2f",x)}
执行后 x = "28。00"
sub( 比对用的{ Regular Expression}, 将替换的新字符串, 原字符串 )
sub( )将原字符串中第一个(最左边)合乎所指定的Regular Expression 的子字符串改以新字符串取代。
第二个参数"将替换的新字符串"中可用"&"来代表"合于条件的子字符串"承上例,执行下列指令:
A = "a6b12anan212。45an6a"
        sub( /(an)+[0-9]*/, "[&]", A)
         结果印出ab12[anan212]。45an6a
sub()不仅可执行取代(replacement)的功用,当第二个参数为空字符串("")时,sub()所执行的是``去除指定字符串''的功用。
藉由 sub()与 match()的搭配使用,可逐次取出原字符串中合乎指定条件的所有子字符串。例如执行下列程序:
awk '
        BEGIN {
              data = "p12-P34 P56-p61"
             while( match( data ,/[0-9]+/) >0) {
                print substr(data,{ RSTART, RLENGTH })
                sub(/[0-9]+/,"")
                }
             }
         ' $*  }
     结果印出 :
               12
               34
               56
               61
sub( )中第三个参数(原字符串)若未指定,则其默认值为。可用 sub( /[9-0]+/,"digital" ) 表示 sub(/[0-9]+/,"digital", )gsub( 比对用的 Regular Expression}, 将替换的新字符串, 原字符串)这个函数与 sub()一样,同样是进行字符串取代的函数。 唯一不同点是gsub()会取代所有合条件的子字符串。
gsub()会传回被取代的子字符串个数。
请参考 sub()。
substr( 字符串,起始位置 [,长度] ):
传回从起始位置起,指定长度之子字符串。 若未指定长度,则传回起始位置到自串末尾之子字符串。
执行下例
      awk {' BEGIN{ print  substr( "User:Wei-Lin Liu", 6)}
    结果印出
       Wei-Lin Liu(2)数学函数
int(x) : 传回x的整数部分(去掉小数)。
           例如 :
               int(7.7) 将传回 7
               int(-7.7) 将传回 -7
sqrt(x) : 传回x的平方根。
           例如 :
           sqart(9) 将传回 3
           若 x 为负数,则执行 sqrt(x)时将造成 Run Time Error
exp(x) : 将传回e的x次方。
           例如 :
           exp(1) 将传回 2.71828
log(x) : 将传回x以e为底的对数值。
           例如 :
                log(e) = 1
           若 x< 0 ,则执行 sqrt(x)时将造成 Run Time Error。
sin(x) : x 须以径度量为单位,sin(x)将传回x的sin函数值。
cos(x) : x 须以径度量为单位,cos(x)将传回x的cos函数值
atan2(y,x) : 传回 y/x 的tan反函数之值,传回值系以径度量为单位。
rand( ) : 传回介于 0与1之间的(近似)随机数值; 0 < rand()<1。除非使用者自行指定rand()函数起始的seed,否则每次执行AWK程序时,  rand()函数都将使用同一个内定的seed,来产生随机数。
srand(x) : 指定以x为rand( )函数起始的seed。若省略了x,则AWK会以执行时的日期与时间为rand()函数起始的seed。
4.AWK内建变量Built-in Variables
因内建变量的个数不多, 此处按其相关性分类说明, 并未按其字母顺序排列。
ARGC 表命令列上除了选项 -F, -v, -f 及其所对应的参数之外的所有参数的个数。若将``AWK程序''直接写于命令列上, 则 ARGC 亦不将该``程序部分''列入计算。ARGV 一个数组用以记录命令列上的参数。
 例 : 执行下列命令
 $awk  -F\t  -v a=8 -f prg。awk  file1。dat file2。dat
 或
 $awk  -F\t  -v a=8 '{ print * a }' file1。dat file2。dat
        }
 执行上列任一程序后
                   ARGC    =  3
                   ARGV[0] = "awk"
                   ARGV[1] = "file1。dat"
                   ARGV[2] = "file2。dat"
  读者请留心 : 当 ARGC = 3 时, 命令列上仅指定 2 个数据文件。
  注 :
       -F\t 表示以 tab 为字段分隔字符 FS(field seporator)。
       -v a=8 是用以 initialize 程序中的变量 a。
FILENAME 用以表示目前正在处理的数据文件文件名。
FS   字段分隔字符。
  表示目前AWK所读入的资料列。
,。。分别表示所读入的资料列之第一栏, 第二栏,。。
(参考下列说明)
当AWK读入一笔资料列  ``A123  8:15'' 时,会先以 记载。故 = "A123  8:15",若程序中进一步使用了 , 。。 或 NF 等内建变量时, AWK才会自动分割 。 以便取得字段相关的数据。 切割后各个字段的数据会分别以 , , 。。。予以记录。
AWK内定(default)的 字段分隔字符(FS) 为 空格符(及tab)。
以本例而言, 读者若未改变 FS, 则分割后 :
第一栏()="A123",  第二栏()="8:15"。
使用者可用 Regexp 自行定义 FS。 AWK每次需要分割数据列时, 会参考目前FS之值。
例如 :
令 FS = "[ :]+" 表示任何由 空白" " 或 ":" 所组成的字符串都可当成分隔字符, 则分割后 :  
第一栏() = "A123", 第二栏() = "8", 第三栏() = "15"
NR 表从 AWK 开始执行该程序后所读取的数据列数。
FNR 与 NR 功用类似。 不同的是AWK每开启一个新的数据文件,
FNR 便从 0 重新累计
NF表目前的资料列所被切分的字段数。
AWK 每读入一笔数据后, 于程序中可以 NF 来得知该笔资料包含
的字段个数。在下一笔数据被读入之前, NF 并不会改变。 但使用者
若自行使用来记录数据  
例如 : 使用 getline, 此时 NF 将代表新的 上所记载之数据的
字段个数。
OFS输出时的字段分隔字符。 默认值 " "(一个空白), 详见下面说明。
ORS输出时数据列的分隔字符。 默认值 "\n"(跳行), 见下面说明。
OFMT数值数据的输出格式。 默认值 "%。6g"(若须要时最多印出6位小数),当使用 print 指令一次印出多项数据时,
例如 : print ,
印出数据时, AWK会自动在 与 之间补上一个 OFS 之值(默认值为 一个空白)
每次使用 print 输出(印)数据后, AWK会自动补上 ORS 之值。(默认值为 跳行)
使用 print 输出(印)数值数据时, AWK将采用 OFMT 之值为输出格式。
例如 : print 2/3
    AWK 将会印出 0.666667  
程序中可藉由改变这些变量之值, 来改变指令 pr
5.Regular Expression 简介
(1)为什么要使用 Regular Expression?
UNIX 中提供了许多 指令 或 tools, 它们具有在档案中 寻找(Search)字符串或置换(Replace)字符串 的功能。 像 grep, vi , sed, awk,。。。不论是找寻字符串或置换字符串, 都得先 ``告诉这些指令所要找寻(被置换)的字符串为何''。若未能预先明确知道所要找寻(被置换)的字符串为何, 只知该字符串存在的范围或特征时。
例如 :
       (一)找寻 ``T0.c'', ``T1.c'', ``T2.c''。。。。 ``T9.c'' 当中的任一字符串。
       (二)找寻至少存在一个 ``A''的任意字符串。
这情况下, 如何告知执行找寻字符串的指令所要找寻的字符串为何。例 (一) 中, 要找寻任一在 ``T'' 与 ``.c'' 之间存在一个阿拉伯数字的字符串;当然您可以列举的方式, 一一把所要找寻的字符串告诉执行命令的指令。但例 (二) 中合于该条件的字符串有无限种可能, 势必无法一一列举。此时,便需要另一种字符串表示的方法(协议)。
(2)什么是 Regular Expression?
Regular Expression(以下简称 (Regexp)是一种字符串表达的方式。 可用以指称具有某特征的所有字符串。注 : 为区别于一般字符串, 本附录中代表 Regexp 的字符串之前皆加
``Regexp''。注 : AWK 程序中常以/。。。。/括住 Regexp; 以区别于一般字符串。
(3)组成 Regular Expression 的元素
普通字符 除了。  * [ ] + ? ( ) \  \^ $ 外之所有字符。由普通字符所组成的Regexp其意义与原字符串字面意义相同。
例如 : Regexp ``the'' 与一般字符串的 ``the'' 代表相同的意义。
.Metacharacter : 用以代表任意一字符。 须留心 UNIX Shell 中使用 ``*''表示 Wildcard, 可用以代表任意长度的字符串。而 Regexp 中使用 ``。'' 来代表一个任意字符。(注意: 并非任意长度的字符串)Regexp 中 ``*'' 另有其它含义, 并不代表任意长度的字符串。
^ 表示该字符串必须出现于行首。  
$ 表示该字符串必须出现于行末。  
例如 :
    Regexp /^The/ 用以表示所有出现于行首的字符串 "The"。
    Regexp /The$/ 用以表示所有出现于行末字符串 "The"。
\ 将特殊字符还原成字面意义的字符(Escape character)
Regexp 中特殊字符将被解释成特定的意义。 若要表示特殊字符的字面(literal meaning)意义时,在特殊字符之前加上"\"即可。
      例如 :
         使用Regexp来表示字符串 ``a。out''时, 不可写成 /a。out/。
         因为 ``。''是特殊字符, 表任一字符。 可合乎 Regexp / a。out/
         的字符串将不只 ``a。out'' 一个; 字符串 ``a2out'', ``a3out'',      
         ``aaout'' 。。。都合于 Regexp /a。out/。
         正确的用法为 :  / a\。out/
[。。。]字符集合, 用以表示两中括号间所有的字符当中的任一个。
例如 : Regexp /[Tt]/ 可用以表示字符 ``T'' 或 ``t''。
     故 Regexp /[Tt]he/ 表示 字符串 ``The'' 或 ``the''。
     字符集合 [。。。 ] 内不可随意留空白。
例如 : Regexp /[ Tt ]/ 其中括号内有空格符, 除表示
      ``T'', ``t'' 中任一个字符, 也可代表一个 `` ''(空格符)
- 字符集合中可使用 ``-'' 来指定字符的区间, 其用法如下 :
Regexp / [0-9]/ 等于 / [0123456789]/ 用以表示任意一个阿拉伯数字。
同理 Regexp /[A-Z]/ 用以表示任意一个大写英文字母。
但应留心 :
Regexp /[0-9a-z]/ 并不等于 /[0-9][a-z]/; 前者表示一个字符,后者表示二个字符。
Regexp /[-9]/ 或 /[9-]/ 只代表字符 ``9''或 ``-''。
[^。。。]使用[^。。] 产生字符集合的补集(complement set)。其用法如下 :
例如 : 要指定 ``T'' 或 ``t'' 之外的任一个字符, 可用 /[^Tt]/ 表之。
同理 Regexp /[^a-zA-Z]/ 表示英文字母之外的任一个字符。
须留心 ``^'' 之位置 : ``^''必须紧接于``["之后, 才代表字符集合的补集
例如 :Regexp /[0-9\^]/ 只是用以表示一个阿拉伯数字或字符"^"。
*  形容字符重复次数的特殊字符。
``*'' 形容它前方之字符可出现 1 次或多次, 或不出现。
例如 :
Regexp /T[0-9]*\.c 中 * 形容其前 [0-9] (一个阿拉伯数字)出现的次数可为 0次或 多次。故Regexp /T[0-9]*\.c/ 可用以表示 ``T.c'', ``T0.c'', ``T1.c''。。。``T9.c''+形容其前的字符出现一次或一次以上。
例如 : Regexp /[0-9]+/ 用以表示一位或一位以上的数字。
?  形容其前的字符可出现一次或不出现。
例如 : Regexp /[+-]?[0-9]+/ 表示数字(一位以上)之前可出现正负号或不出现正负号。

(。。。)用以括住一群字符,且将之视成一个group(见下面说明)
       例如 :
      Regexp /12+/   表示字符串 ``12'', ``122'', ``1222'', ``12222'',。。。
      Regexp /(12)+/ 表示字符串 ``12'', ``1212'', ``121212'', ``12121212''。。。。上式中 12 以( )括住, 故 ``+''所形容的是 12, 重复出现的也是 12。
| 表示逻辑上的"或"(or)
例如 :
Regexp / Oranges? | apples?  | water/ 可用以表示 :
  字符串 ``Orange'', ``oranges'' 或 ``apple'', ``apples''  或 ``water''
match是什么 ?  
讨论 Regexp 时, 经常遇到 ``某字符串合于( match )某 Regexp''的字眼。
其意思为 :  ``这个 Regexp 可被解释成该字符串''。
[ 例如] :
字符串 "the" 合于(match) Regexp /[Tt]he/。因为 Regexp /[Tt]he/ 可解释成字符串 "the" 或 "The", 故字符串 "the" 或 "The"都合于(match) Regexp /[Th]he/。AWK 中提供二个关系操作数(Relational Operator,见注一) ~ !~, 它们也称之为 match, not match。但函义与一般常称的 match 略有不同。
其定义如下 :
A  表一字符串, B 表一 Regular Expression
只要 A 字符串中存在有子字符串可 match( 一般定义的 match) Regexp  B ,
则 A ~B 就算成立, 其值为 true, 反之则为 false。
! ~ 的定义与~恰好相反。

例 如 :
         "another" 中含有子字符串 "the" 可 match Regexp /[Tt]he/ , 所以
         "another" ~/[Tt]he/  之值为 true。
[注 一] : 有些论著不把这两个操作数( ~, !~)与 Relational Operators 归为一类。
(4)应用 Regular Expression 解题的简例下面列出一些应用 Regular Expression 的简例, 部分范例中会更动 之值, 若您使用的 AWK不容许使用者更动 时, 请改用 gawk。  
将档案中所有的字符串 "Regular Expression" 或 "Regular expression" 换成 "Regexp"
awk '
  {   gsub( /Regular[ \t]+[Ee]xpression/, "Regexp")
      print
  }
 ' $*
去除档案中的空白行(或仅含空格符或tab)
awk '
      !~ /^[ \t]*$/  {  print   }
' $*
在档案中俱有 ddd-dddd(电话号码型态, d 表digital)的字符串前加上"TEL : "
awk '
   {   gsub( /[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/, "TEL : &" )
       print
   }
 ' $*
从档案的 Fullname 中分离出 路径 与 文件名
awk '
BEGIN{
       Fullname = "/usr/local/bin/xdvi"
       match( Fullname, /。*\//)
       path = substr(Fullname, 1, RLENGTH-1)
       name = substr(Fullname, RLENGTH+1)
       print "path :", path,"  name :",name
     }
    ' $*
结果印出
   path : /usr/local/bin   name : xdvi
将某一数值改以现金表示法表之(整数部分每三位加一撇,且含二位小数)
awk '
BEGIN {
        Number = 123456789
        Number = sprintf("$%。2f",Number)
        while( match(Number,/[0-9][0-9][0-9][0-9]/ ) )
               sub(/[0-9][0-9][0-9][。,]/, ",&", Number)
        print Number
      }
  ' $*
结果印出
   3,456,789。00
把档案中所有具 ``program数字。f''形态的字符串改为
``[Ref : program数字.c]''
awk '
   {   while( match( , /program[0-9]+\。f/ )  ){
          Replace = "[Ref : " substr( , RSTART, RLENGTH-2) ".c]"
          sub( /program[0-9]+\。f/, Replace)
        }
       print
    }
 ' $*


I/O重定向 详解及例子(转载):【上一篇】
AWK Tutorial Guide—补:【下一篇】
【相关文章】
  • 分析tuxedo的service时间日志的awk脚本.
  • awk将文件的两行合并为一行
  • awk 学习指南
  • Tutorial on DiskSuite
  • Tutorial on NIS
  • Tutorial on Sendmail
  • MRTG-Unix-Guide
  • AE language pack troubleshooting guide
  • awk 教程 2
  • awk 教程 1
  • 【随机文章】
  • 组合框(一)
  • Color所能做到的一些ps效果
  • Taglib打包部署和使用方式
  • 上传图片
  • VS2005下开发数据窗口控件,及数据窗口列,即表中表的实现。大家关注!
  • Apache HTTP服务器 2.0版本文档--[加精]
  • [ZT]C++程序设计之四书五经
  • 用osworkflow写一个请假例子(提供代码下载)
  • 有条件的同步方法
  • XML简易教程之三
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.