【译】 AWK教程指南 2概述

2.1 为什么用AWK

  由于awk具有上述特色,在问题处理的过程中,可轻易使用awk来撰写一些小工具;这些小工具并非用来解决整个大问题,它们只扮演解决个别问题过程的某些角色,可通过Shell所提供的pipe将数据按需要传送给不同的小工具进行处理,以解决整个大问题。这种解题方式,使得这些小工具可因不同需求而被重复组合及使用(reuse);也可通过这种方式来先行测试大程序原型的可行性与正确性,将来若需要较高的执行速度时再用C语言来改写。这是awk最常被应用之处。若能常常如此处理问题,读者可以以更高的角度来思考抽象的问题,而不会被拘泥于细节的部分。本手册作为awk入门的学习指引,其内容将先强调如何撰写awk程序,未列入进一步解题方式的应用实例,这部分将留待UNIX进阶手册中再行讨论。

2.2 如何取得awk

  一般的UNIX操作系统,本身即带有awk。不同的UNIX操作系统所带的awk其版本亦不尽相同。若读者所使用的系统上未带有awk,可通过anonymous
ftp到下列地方取得:

    phi.sinica.edu.tw:/pub/gnu

    ftp.edu.tw:/UNIX/gnu

    prep.ai.mit.edu:/pub/gnu

2.3 awk如何工作

  为便于解释awk程序架构,及有关术语(terminology),先以一个员工薪资数据文件(emp.dat),来加以介绍。

              

  数据文件中各字段依次为 员工ID、姓名、时薪 及
实际工时。ID中的第一个字母为部门识别码,"A"、"P"分别表示"组装"及"包装"部门。

  本小节着重于说明awk程序的主要架构及工作原理,并对一些重要的名词加以必要的解释。通过学习这部分内容,读者可体会出awk语言的主要精神及awk与其它语程序言的差别。为便于说明,之后以条列方式说明。

  • 名词定义

  1.
记录(Record):awk从数据文件上读取数据的基本单位。以上列数据文件emp.dat为例,awk读入的

      第一条记录是 "A125  Jenny  100
 210"

      第二条记录是 "A341  Dan    110
 215"

  一般而言, 一条 记录 就相当于数据文件上的一行资料。 (参考 : 附录 B
内建变量"RS")

  2. 字段(Field):为记录中被分隔开的子字符串。以数据行"A125 Jenny
100 210"为例,












第一个 第二个 第三个 第四个
“A125" "Jenny" 100 210

  一般是以空格符来分隔相邻的字段。( 参考:附录 D 内建变量"FS"
)

  • 如何执行AWK

  在UNIX的命令行上输入下列格式的指令:("$"表示Shell命令行上的提示符号) 


    $  awk  ‘awk程序‘   数据文件名

  则awk会先编译该程序,然后执行该程序来处理所指定的数据文件。(上述方式直接把程序写在UNIX的命令行上)

  • awk程序的主要结构:

  awk程序中主要语法是  Pattern { Actions
},故常见的awk程序其形式如下:

      Pattern1 { Actions1 }

      Pattern2 { Actions2 }

      ......

      Pattern3 { Actions3
}

  • Pattern 是什么 ?

  awk 可接受许多不同形式的 Pattern。一般常使用
"关系表达式"(Relational expression)来当作 Pattern。

  例如:

    x > 34 是一个Pattern,判断变量 x 与 34
是否存在大于的关系。

    x == y 是一个Pattern,判断变量 x 与变量 y
是否存在等于的关系。

    上式中 x >34 、 x == y
便是典型的Pattern。

  

  awk 提供 C 语言中常见的关系运算符(Relational Operators)
如 >, <, >=, <=, ==, !=。此外,awk 还提供 ~ (match) 及 !~(not match)
二个关系运算符(注一)。

  其用法与涵义如下:

    若 A 为一字符串,B 为一正则表达式(Regular
Expression)

      A ~ B 判断 字符串A 中是否 包含
能匹配(match)B表达式的子字符串。

      A !~ B 判断 字符串A 中是否 不包含
能匹配(match)B表达式的子字符串。

  例如 :

    "banana" ~ /an/  
整个是一个Pattern。

  因为"banana"中含有可以匹配 /an/
的子字符串,故此关系式成立(true),整个Pattern的值也是true。

  相关细节请参考 附录 A Patterns, 附录 E Regular
Expression  

(注一:) 有少数awk文献,把 ~, !~ 当成另一类的 Operator,并不视为一种
Relational Operator。本手册中将这两个运算符当成一种 Relational Operator。

  • Actions 是什么?

  Actions 是由许多awk指令构成。而awk的指令与 C
语言中的指令十分类似。

  例如:

    awk的 I/O指令:print, printf( ), getline,
...

    awk的 流程控制指令:if(...){..} else{..},
while(...){...}, ...

    (请参考 附录 B --- "Actions" )

  • awk 如何处理 Pattern { Actions }
    ?

  awk 会先判断(Evaluate) 该 Pattern 的值,若 Pattern
判断后的值为true (或不为0的数字,或不是空的字符串),则awk将执行该 Pattern 所对应的 Actions。反之,若 Pattern 的值不为
true,则awk将不执行该 Pattern所对应的 Actions。

  例如:若awk程序中有下列两指令

    50 > 23        {print "Hello!
The word!!" }

    "banana" ~ /123/  {print "Good
morning !" }

  awk会先判断 50 >23
是否成立。因为该式成立,所以awk将打印出"Hello! The word!!"。而另一 Pattern 为"banana"~/123/,因为"banana"
内未含有任何子字符串可 match /123/,该 Pattern 的值为false,故awk将不会打印出 "Good morning
!"

  • awk 如何处理{ Actions }
    的语法?(缺少Pattern部分)

  有时语法 Pattern { Actions }中,Pattern 部分被省略,只剩
{Actions}。这种情形表示 "无条件执行这个 Actions"。

  • awk 的字段变量

  awk 所内建的字段变量及其涵意如下 :


















字段变量

含义

$0

一字符串,其内容为目前 awk 所读入的整行数据。

$1

$0 上第一个字段的数据。

$2

$0 上第二个字段的数据。

...

其余类推

  • 读入数据行时,awk如何更新(update)这些内置的字段变量?

  1. 当 awk 从数据文件中读取一行数据时,awk 会使用内置变量$0
予以记录。

  2. 每当 $0 被改动时 (例如:读入新的数据行 或 自行变更 $0)
awk 会立刻重新分析 $0 的字段情况,并将 $0 上各字段的数据用 $1、$2、...等予以记录。

  • awk的内置变量(Built-in
    Variables)

  awk
提供了许多内置变量,使用者在程序中可使用这些变量来取得相关信息(不用加$)。常见的内置变量有:















内置变量

含义

NF (Number of Fields)

为一整数,其值表示$0上所存在的字段总数。

NR (Number of Records)

为一整数,其值表示awk已读入的数据行数目。

FILENAME

awk正在处理的数据文件名。

  例如 : awk 从数据文件 emp.dat 中读入第一行记录"A125 Jenny
100 210" 之后,程序中:

    $0 的值将是 "A125 Jenny 100 210"

    $1 的值为 "A125"   
 $2 的值为 "Jenny"

    $3 的值为 100      $4
的值为 210

    NF 的值为 4          
$NF 的值为 210 (笔者注:$NF即为$4)

    NR 的值为 1        
        FILENAME 的值为 "emp.dat"

  • awk的工作流程 :

  执行awk时,它会反复进行下列四步骤。

    1. 自动从指定的数据文件中读取一个数据行。

    2. 自动更新(Update)相关的内置变量的值。如:NF, NR,
      $0...

    3. 依次执行程序中 所有 的 Pattern { Actions }
      指令。

    4. 当执行完程序中所有 Pattern { Actions }
      时,若数据文件中还有未读取的数据,则反复执行步骤1到步骤4。

  awk会自动重复进行上述4个步骤,使用者不须在程序中编写这个循环
(Loop)。

【译】 AWK教程指南 2概述,布布扣,bubuko.com

时间: 2024-10-04 18:18:32

【译】 AWK教程指南 2概述的相关文章

【译】 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教程指南 1前言

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

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

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

【译】 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 exi

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

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

【译】 AWK教程指南 8处理多行数据

awk 每次从数据文件中只读取一行数据进行处理.awk是依照其内置变量 RS(Record Separator) 的定义将文件中的数据分隔成一行一行的Record.RS 的默认值是 "\n"(换行符),故平常awk中一行数据就是一条 Record. 但有些文件中一条Record涵盖了多行数据,这种情况下不能再以 "\n" 来分隔Records.最常使用的方法是相邻的Records之间改以 一个空白行 来隔开. 在awk程序中,令 RS = ""(

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

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

【译】 AWK教程指南 6在AWK程序中使用Shell命令

awk程序中允许调用Shell指令,并提供管道解决awk与系统间数据传递的问题.所以awk很容易使用系统资源,读者可利用这个特点来编写某些适用的系统工具. 范例:写一个awk程序来打印出线上人数. 将下列程序建文件,命名为 count.awk BEGIN { while ( "who" | getline ) n++ print n } 并执行下列命令: $ awk -f count.awk 执行结果将会打印出目前在线人数. 说 明: 1. awk 程序并不一定要处理数据文件,以本例而