如果你不是很熟悉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) |