Chinaunix首页 | 论坛 | 博客
  • 博客访问: 365192
  • 博文数量: 56
  • 博客积分: 1941
  • 博客等级: 上尉
  • 技术积分: 587
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-11 21:50
文章分类

全部博文(56)

文章存档

2015年(1)

2014年(4)

2013年(2)

2012年(4)

2011年(8)

2010年(37)

分类: LINUX

2010-06-11 22:58:52

如果你不是很熟悉UNIX的话,你可能对Awk会有些陌生,的确,AWK作为一种
  优良的文本处理工具还没有达到它应有的普及程度。但是它却得 到了熟悉并经常
  使用它的人们的一致称赞。
  AWK到底是什么?从字面上看,“AWK”这三个字母几乎不能给我们任何提示,
   他不象一些UNIX命令一样多多少少反映出了一些功能,如FIND和KILL一样,也不
  象另一些UNIX命令是功能的简写,如l是 list(列表)的缩写,这些都能给我们多多
  少少一点提示,但awk不行. 事实上,AWK是三个程序大师首字符的缩写,这三个
   人分别是:Aho、(Peter)Weinberg和(Brain)Kernighan。正是这三个人创造
  了AWK。显然,这样的词汇组成形 式不能给我们提供任何的帮助。
  那么:AWK的功能到底是什么呢?实际上AWK是一种文本文件处理工具,这一点
  与sed和grep 很相似,但awk所提供的功能却是sed和grep所无法望其项背的。awk提
  供了极其强大的功能:可以进行样式装入、流控制、数学运算符、 进程控制语句甚
  至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。
  实际上awk的确拥有自己的语 言:awk程序设计语言,awk的三位创建者已将它正式
  定义为“样式扫描和处理语言”。
  即使如此,你也许还要问:我为什么要用 awk?的确,unix拥有很多优秀的工具,
  便如C语言就是一种功能强大的武器,我们又为什么要选择awk呢?这首先是因为
   awk是一个容易得到的工具:几乎每个UNIX系统都带有自己的awk,而C语言却是UNIX
  开发系统的一部分,如果你没有安装UNIX开发 系统的话,你就不可能得到C语言。其
  次,awk是一个使用简单的工具,有些问题也许C语言可以解决,但你却不得不通过
  写源程序、 调试、编译等等繁琐的步骤,而awk就根本不存在这个问题。最后,awk
  在实现某些功能方面,的确是比C语言更为便捷的工具,而这些却是更简 单一些的
  工具例如shell和处理文件所无法实现的。例如我曾经试图用shell script写一个
  实现销售清单上销售金额的 累加,然而shell只提供了整数型的数据变量,对于小数
  点后面的两位就无能为力了,而为了一个临时性的工作专门写一个C程序似乎又不值
   得,最后我想到了awk,结果非常轻松的实现了,也正是从那时起,我开始喜欢上
  awk了。在这里有一个可遵循的一般原则:如果你用普通的 shell工具或shell script
  有困难的话,试试awk,如果awk仍不能解决问题,则便用C语言,如果C语言仍然失败,
   则移至C++。
  
  看了对awk的简要介绍,你也许对awk有学习和掌握的愿望了,既然如此,就让我
  们开始探索awk 的新旅程吧!
  
  一、awk的语法。
  
  awk是以unix的一个命令的形式提供给用户的,你可以在/bin目 录下找到awk这个文
  件,如果缺少这个文件,你就不能运行awk。因此,awk拥有自己的调用语法:
  
  awk [ -F re][parameter...]['prog'][-f progfile][in_file...]
  
  参数说明:
   re awk记录分隔符。
  parameter 该参数帮助为不同的变量赋值。
  'prog' awk的程序语句。(注意这里必须用单拓号:'和'括起,以防被shell
  解释)
  progfile awk程序文件。
   in_file 输入文件,可以有多个。值得注意的是awk不修改输入文件。如果未
  指定输入文件,awk将接受标准输入,并将结果显示在标 准输出上。awk支持输入输出重
  定向(<、>、>>、<<以及|)。
  awk支持模式匹配, 若没有给出模式,则对于输入文件中的所有行都有匹配的。
  
  二、简单的应用:
  例1:显示文件myfile中含有字符 串"sun"的所有行:
  awk '/sun/ {print}' myfile
  在这里,模式/sun/匹配输入文件myfile 中所有含有字符串'sun'的行并对其进行操作,
  而程序语句print完成对该行的打印。
  你也可以使用,号分开两模式以选定某个 范围:
  例2:显示文件myfile中第一个匹配Sun或sun的行与第一个匹配Moon或moon行之间
  的行:
   awk '/[Ss]un/,/[Mm]oon/ {print}' myfile
  
  三、awk的字段:
  awk的一个 强大的功能是支持对字段的操作,这是grep和sed不能实现的。
  
  所谓的字段,即是行中的一部分。在awk中,一般的情况下,将 文本文件中的一行视
  为一个记录,而将行中的不同部分称为“字段”。awk用$1,$2...的形式顺序的表示行中的
  不同部分即不 同字段。一般情况下awk将空白符视为字段间的分隔符,在awk中,用一个内
  置的FS变量来确定所使用的字段分隔符。awk允许用-F先项改 变默认的字段分隔符。同样,
  在awk中你也可以通过修改记录分隔符变量RS来改变默认的记录分隔符。
  在awk中用内置变量NR来 表示当前工作的记录数。我们可以将其应用于模式匹配中用
  来指定工作范围:
  例3:显示文本文件myfile中第七行到第十五行中以 字符%分隔的第一字段,第三字段和
  第七字段:
  awk -F % 'NR==7,NR==15 {printf $1 $3 $7}' myfile
  
  四、printf语句
  
  awk可以通过调用用一对单引号括起来的一系列语句来完成 一些较为复杂的功能。前面
  我们已经遇到过的print就是awk的语句之一。awk也支持独立的awk程序的调用,其方法是在
  命 令行中加上-f <程序文件名>参数。
  awk融合了许多C语言的待点,因此,如果你熟悉C语言的话对使用awk将有极大的帮助,
   实际上,awk中有许多引用形式都是从C语言借用过来的,如我们下面要看到的printf函数就
  是一个例子。
  如果你熟悉C语 言,你也许会怀念其中的printf函数,它提供的强大格式输出功能曾经
  带我们许多的方便。幸运的是,我们在awk中又和它重逢了。awk中 printf几乎与C语言中一模
  一样,如果你熟悉C语言的话,你完全可以照C语言的模式使用awk中的printf。因此在这里,
   我们只给出一个例子,如果你不熟悉的话,请随便找一本C语言的入门书翻翻。
  例4:显示文件myfile中的行号和第3字段:
   $awk '{printf"%03d%s\n",NR,$1}' myfile
  值得注意的一点是awk中的内置变量(如这里的NR)不须要 以$开头。
  对于awk中的其它语句,我们将在后面继续讨论。
  
  五、awk程序设计
  
  前面曾经说 过awk提供了整套程序设计语言,包括变量、关系判断、流程控制等等,下面
  我们分别说说其中的用法:
  
  (一)、变量:
   awk允许在程序语言中设置变量,事实上,提供变量的功能是程序设计语言的其本要求,
  不提供变量的程序设计语言本人还从未见过。awk提供 两种变量,一种是awk内置的变量,如前面
  提到的NR、RS都属于此种范畴,如果你还知道awk提供了哪些其它的内置变量,请参考本文后面
   的附录。awk也允许用户在awk程序语句中定义并调用自已的变量。与C语言不同的是,awk中不需
  要对变量进行初始化,awk根据其在 awk中第一次出现的形式和上下文确定其具体的数据类型。
  当变量类型不确定时,awk设定其为字符串类型。
  (二)、运算与判断:
   awk支持C语言提供的大多数运算:如+、-、*、/、%等等,也支持关系判断,如<、>、>=
  等等,也支持用逻辑运算 符:!(非)、&&(与)、||(或)和()进行多重判断,这大大增强了awk
  的功能。
  awk也支持C语言中类 似++、--、+=、-=、=+、=-之类的功能,这给熟悉C语言的使用者编写
  awk程序带来了极大的方便。
  在awk中为了实现 某些运算功能,提供了一些内置的函数,如log、sqr、cos、sin等等,同
  时,awk也提供了用于对字符串进行操作(运算)的函数如 length、substr等等。
  awk提供的具体的运算与判断功能请参考文后的附录。
  (三)、流程控制
  awk提供 了完备的类似C语言的流程控制语句,这给我们编程带来了极大的方便。
  1、BEGIN和END
  在awk中两个特别的表达 式,BEGIN和END可用于pattern中,任何在BEGIN之后列出的操作(
  在{}内)将在awk开始扫描输入之前执行,而END之后 列出的操作将在扫描完全部的输入之后报废行。
  因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。
   例5:累计销售文件xs中的销售金额(假设销售金额在记录的第三字段):
  
  $awk
  >'BEGIN { FS=":";print "统计销售金额";total=0}
  >{print $3;total=total+$3;}
   >END {printf "销售金额总计:%.2f",total}' sx
  (注:>是shell提供的第二提示符,如要在 shell程序awk语句和awk语言中换行,则需在行尾加
  反斜杠\)
  
  在这里BEGIN预置了内部变量FS(字段分 隔符)和自定义变量total,同时在扫描之前显示出输出
  行头。而END则在扫描完成后打印出总合计。
  
  2、流程控制 语句
  awk提供了完备的流程控制语句,其用法与C语言类似。下面我们一一加以说明:
  
  if...else语句:
   
  格式:
  if(表达式)
  语句1
  else
  语句2
  
  格式中"语句1"可 以是多个语句,如果你为了方便awk判断也方便你自已阅读,你最好将多个语句
  用{}括起来。
  awk分枝结构允许嵌套,其格式为
   if(表达式1)
  {if(表达式2)
  语句1
  else
  语句2
  }
  语句3
   else {if(表达式3)
  语句4
  else
  语句5
  }
  语句6
  当然实际操作过 程中你可能不会用到如此复杂的分枝结构,这里只是为了给出其样式罢了。
  
  while语句
  
  格式为
   while(表达式)
  语句
  
  for语句
  
  格式为:
  
  for(初始表达 式;终止条件;步长表达式)
  语句
  
  在awk while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的
  语句来退出。
  
   好了,awk就介绍到这里,说实在话,就这些内容都是awk的初步知识,电脑永远是前进的科学,
  要想跟上它的步伐就得不断前行,但愿本篇能 在你前行的漫漫长途中铺平一段小小的路程,能如此,则
  愿已偿。
  如对本篇有任何疑问,请E-mail To:Chizlong@yeah.net或到主页中留言。
  
  
  附 录:
  
  awk内置变量
  
  变量名 含义
  
  ARGC 命令行参数个数
  ARGV 命令行参数数组
  FILENAME string=当前输入的文件名
  FNR 在当前文件中当前记录数(对输入文件起始为1)
  FS 输入字段分隔符
  NF 当前记录的字段数
  NR 当前记录数(为全部输入文件)
  OFMT 数值的输出格式(默认为%.6g)
  OFS 输出字段的分隔符(默认为空格)
  ORS 输出记录分隔符(默认为换行符)
  RS 输入记录分隔符(默认为换行符)
  
  
  awk允许的测试:
   
  操作符 含义
  
  x==y x等于y?
  x!=y x不等于y?
  x>y x大于y?
   x>=y x大于或等于y?
  x
  x<=y x小于或等于y?
  x~re x匹配正则表达式re?
  x!~re x不匹配正则表达式re?
  
  awk的操作符(按优先级升序排列)
  
   = 、+=、 -=、 *= 、/= 、 %=
  ||
  &&
  > >= < <= == != ~ !~
  xy (字符串连结,'x''y'变成"xy")
  + -
  * / %
   ++ --
  
  awk的函数
  
int(x) 对x取整
rand 取 0到1之间的随机数
srand(x) 设置x为rand的新输入值
cos(x) 给出x的余弦值
sin(x) 给出x的正弦值
atan2(x,y) 给出y/x的正切值
exp(x) 给出e的x次幂
log(x) 给出x的常用对数值(基为e)
sqrt(x) 给出x的正平方根值
exit(x) 结束awk程序,若有x值,则返回x,否则返回0.
index(s,t) 返回t在s中的第一个开始位置,如t不是s的子串,则返回0]
length(x) 求x的长度(字符个数)
substr(s,x,y) 在字符串s中取得从x个字符开始的长度为y的子字符串.
阅读(646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~