awk详解.docx
- 文档编号:7755081
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:21
- 大小:26.12KB
awk详解.docx
《awk详解.docx》由会员分享,可在线阅读,更多相关《awk详解.docx(21页珍藏版)》请在冰豆网上搜索。
awk详解
awk是一种程序语言,对文档资料的处理具有很强的功能。
awk名称是由它三个最初设计
者的姓氏的第一个字母而命名的:
AlfredV.Aho、PeterJ.Weinberger、BrianW.Kernighan。
awk最初在1977年完成。
1985年发表了一个新版本的awk,它的功能比旧版本增强了不少。
awk
能够用很短的程序对文档里的资料做修改、比较、提取、打印等处理。
如果使用C或Pascal
等语言编写程序完成上述的任务会十分不方便而且很花费时间,所写的程序也会很大。
awk不仅仅是一个编程语言,它还是Linux系统管理员和程序员的一个不可缺少的工具。
awk语言本身十分好学,易于掌握,并且特别的灵活。
gawk是GNU计划下所做的awk,gawk最初在1986年完成,之后不断地被改进、更新。
gawk包含awk的所有功能。
6.1gawk的主要功能
gawk的主要功能是针对文件的每一行(line),也就是每一条记录,搜寻指定的格式。
当某
一行符合指定的格式时,gawk就会在此行执行被指定的动作。
gawk依此方式自动处理输入文
件的每一行直到输入文件档案结束。
gawk经常用在如下的几个方面:
•根据要求选择文件的某几行,几列或部分字段以供显示输出。
•分析文档中的某一个字出现的频率、位置等。
•根据某一个文档的信息准备格式化输出。
•以一个功能十分强大的方式过滤输出文档。
•根据文档中的数值进行计算。
6.2如何执行gawk程序
基本上有两种方法可以执行gawk程序。
如果gawk程序很短,则可以将gawk直接写在命令行,如下所示:
gawk'program'input-file1input-file2...
其中program包括一些pattern和action。
如果gawk程序较长,较为方便的做法是将gawk程序存在一个文件中,
gawk的格式如下所示:
gawk-fprogram-fileinput-file1input-file2...
gawk程序的文件不止一个时,执行gawk的格式如下所示:
gawk-fprogram-file1-fprogram-file2...input-file1input-file2...
6.3文件、记录和字段
一般情况下,gawk可以处理文件中的数值数据,但也可以处理字符串信息。
如果数据没有
存储在文件中,可以通过管道命令和其他的重定向方法给gawk提供输入。
当然,gawk只能处
理文本文件(ASCII码文件)。
电话号码本就是一个gawk可以处理的文件的简单例子。
电话号码本由很多条目组成,每一
个条目都有同样的格式:
姓、名、地址、电话号码。
每一个条目都是按字母顺序排列。
在gawk中,每一个这样的条目叫做一个记录。
它是一个完整的数据的集合。
例如,电话号
码本中的SmithJohn这个条目,包括他的地址和电话号码,就是一条记录。
记录中的每一项叫做一个字段。
在gawk中,字段是最基本的单位。
多个记录的集合组成了
一个文件。
大多数情况下,字段之间由一个特殊的字符分开,像空格、TAB、分号等。
这些字符叫做
字段分隔符。
请看下面这个/etc/passwd文件:
tparker;t36s62hsh;501;101;TimParker;/home/tparker;/bin/bash
etreijs;2ys639dj3h;502;101;EdTreijs;/home/etreijs;/bin/tcsh
ychow;1h27sj;503;101;YvonneChow;/home/ychow;/bin/bash
你可以看出/etc/passwd文件使用分号作为字段分隔符。
/etc/passwd文件中的每一行都包括
七个字段:
用户名;口令;用户ID;工作组ID;注释;home目录;启始的外壳。
如果你想要
查找第六个字段,只需数过五个分号即可。
但考虑到以下电话号码本的例子,你就会发现一些问题:
SmithJohn13WilsonSt.555-1283
SmithJohn2736ArtsideDrApt123555-2736
SmithJohn125WestmountCr555-1726
虽然我们能够分辨出每个记录包括四个字段,但gawk却无能为力。
电话号码本使用空格作
为分隔符,所以gawk认为Smith是第一个字段,John是第二个字段,13是第三个字段,依次类
推。
就gawk而言,如果用空格作为字段分隔符的话,则第一个记录有六个字段,而第二个记
录有八个字段。
所以,我们必须找出一个更好的字段分隔符。
例如,像下面一样使用斜杠作为字段分隔
符:
Smith/John/13WilsonSt./555-1283
Smith/John/2736ArtsideDr/Apt/123/555-2736
Smith/John/125WestmountCr/555-1726
如果你没有指定其他的字符作为字段分隔符,那么gawk将缺省地使用空格或TAB作为字段
分隔符。
6.4模式和动作
在gawk语言中每一个命令都由两部分组成:
一个模式(pattern)和一个相应的动作
(action)。
只要模式符合,gawk就会执行相应的动作。
其中模式部分用两个斜杠括起来,而动
作部分用一对花括号括起来。
例如:
/pattern1/{action1}
/pattern2/{action2}
/pattern3/{action3}
所有的gawk程序都是由这样的一对对的模式和动作组成的。
其中模式或动作都能够被省
略,但是两个不能同时被省略。
如果模式被省略,则对于作为输入的文件里面的每一行,动作
都会被执行。
如果动作被省略,则缺省的动作被执行,既显示出所有符合模式的输入行而不做
任何的改动。
下面是一个简单的例子,因为gawk程序很短,所以将gawk程序直接写在外壳命令行:
gawk'/tparker/'/etc/passwd
此程序在上面提到的/etc/passwd文件中寻找符合tparker模式的记录并显示(此例中没有动
作,所以缺省的动作被执行)。
让我们再看一个例子:
gawk'/UNIX/{print$2}'file2.data
此命令将逐行查找file2.data文件中包含UNIX的记录,并打印这些记录的第二个字段。
你也可以在一个命令中使用多个模式和动作对,例如:
gawk'/scandal/{print$1}/rumor/{print$2}'gossip_file
此命令搜索文件gossip_file中包括scandal的记录,并打印第一个字段。
然后再从头搜索
gossip_file中包括rumor的记录,并打印第二个字段。
6.5比较运算和数值运算
gawk有很多比较运算符,下面列出重要的几个:
==相等
!
=不相等
>大于
<小于
>=大于等于
<=小于等于
例如:
gawk'$4>100'testfile
将会显示文件testfile中那些第四个字段大于100的记录。
下表列出了gawk中基本的数值运算符。
运算符说明示例
+加法运算2+6
-减法运算6-3
*乘法运算2*5
/除法运算8/4
^乘方运算3^2(=9)
%求余数9%4(=1)
例如:
{print$3/2}
显示第三个字段被2除的结果。
在gawk中,运算符的优先权和一般的数学运算的优先权一样。
例如:
{print$1+$2*$3}
显示第二个字段和第三个字段相乘,然后和第一个字段相加的结果。
你也可以用括号改变优先次序。
例如:
{print($1+$2)*$3}
显示第一个字段和第二个字段相加,然后和第三个字段相乘的结果。
6.6内部函数
gawk中有各种的内部函数,现在介绍如下:
6.6.1随机数和数学函数
sqrt(x)求x的平方根
sin(x)求x的正弦函数
cos(x)求x的余弦函数
atan2(x,y)求x/y的余切函数
log(x)求x的自然对数
exp(x)求x的e次方
int(x)求x的整数部分
rand()求0和1之间的随机数
srand(x)将x设置为rand()的种子数
6.6.2字符串的内部函数
•index(in,find)在字符串in中寻找字符串find第一次出现的地方,返回值是字符串
find出现在字符串in里面的位置。
如果在字符串in里面找不到字符串find,则返回值为
0。
例如:
printindex("peanut","an")
显示结果3。
•length(string)求出string有几个字符。
例如:
length("abcde")
显示结果5。
•match(string,regexp)在字符串string中寻找符合regexp的最长、最靠左边的子字
符串。
返回值是regexp在string的开始位置,即index值。
match函数将会设置系统变量
RSTART等于index的值,系统变量RLENGTH等于符合的字符个数。
如果不符合,则会
设置RSTART为0、RLENGTH为-1。
•sprintf(format,expression1,...)和printf类似,但是sprintf并不显示,而是返回字符
串。
例如:
sprintf("pi=%.2f(approx.)",22/7)
返回的字符串为pi=3.14(approx.)
•sub(regexp,replacement,target)在字符串target中寻找符合regexp的最长、最靠左的
地方,以字串replacement代替最左边的regexp。
例如:
str="water,water,everywhere"
sub(/at/,"ith",str)
结果字符串str会变成
wither,water,everywhere
•gsub(regexp,replacement,target)与前面的sub类似。
在字符串target中寻找符合
regexp的所有地方,以字符串replacement代替所有的regexp。
例如:
str="water,water,everywhere"gsub(/at/,"ith",str)
结果字符串str会变成
wither,wither,everywhere
•substr(string,start,length)返回字符串string的子字符串,这个子字符串的长度为
length,从第start个位置开始。
例如:
substr("washington",5,3)
返回值为ing
如果没有length,则返回的子字符串是从第start个位置开始至结束。
例如:
substr("washington",5)
返回值为ington。
•tolower(string)将字符串string的大写字母改为小写字母。
例如:
tolower("MiXeDcAsE123")
返回值为mixedcase123。
•toupper(string)将字符串string的小写字母改为大写字母。
例如:
toupper("MiXeDcAsE123")
返回值为MIXEDCASE123。
6.6.3输入输出的内部函数
•close(filename)将输入或输出的文件filename关闭。
•system(command)此函数允许用户执行操作系统的指令,执行完毕后将回到gawk程
序。
例如:
BEGIN{system("ls")}
6.7字符串和数字
字符串就是一连串的字符,它可以被gawk逐字地翻译。
字符串用双引号括起来。
数字不能
用双引号括起来,并且gawk将它当作一个数值。
例如:
gawk'$1!
="Tim"{print}'testfile
此命令将显示第一个字段和Tim不相同的所有记录。
如果命令中Tim两边不用双引号,
gawk将不能正确执行。
再如:
gawk'$1=="50"{print}'testfile
此命令将显示所有第一个字段和50这个字符串相同的记录。
gawk不管第一字段中的数值
的大小,而只是逐字地比较。
这时,字符串50和数值50并不相等。
6.8格式化输出
我们可以让动作显示一些比较复杂的结果。
例如:
gawk'$1!
="Tim"{print$1,$5,$6,$2}'testfile
将显示testfile文件中所有第一个字段和Tim不相同的记录的第一、第五、第六和第二个字
段。
进一步,你可以在print动作中加入字符串,例如:
gawk'$1!
="Tim"{print"Theentryfor",$1,"isnotTim.",$2}'testfile
print动作的每一部分用逗号隔开。
借用C语言的格式化输出指令,可以让gawk的输出形式更为多样。
这时,应该用printf而不
是print。
例如:
{printf"%5slikesthislanguage\n",$2}
printf中的%5s部分告诉gawk如何格式化输出字符串,也就是输出5个字符长。
它的值由
printf的最后部分指出,在此是第二个字段。
\n是回车换行符。
如果第二个字段中存储的是人
名,则输出结果大致如下:
Timlikesthislanguage
Geofflikesthislanguage
Mikelikesthislanguage
Joelikesthislanguage
gawk语言支持的其他格式控制符号如下:
•c如果是字符串,则显示第一个字符;如果是整数,则将数字以ASCII字符的形式显示。
例如:
printf“%c”,65
结果将显示字母A。
•d显示十进制的整数。
•i显示十进制的整数。
•e将浮点数以科学记数法的形式显示。
例如:
print“$4.3e”,1950
结果将显示1.950e+03。
•f将数字以浮点的形式显示。
•g将数字以科学记数法的形式或浮点的形式显示。
数字的绝对值如果大于等于0.0001则
以浮点的形式显示,否则以科学记数法的形式显示。
•o显示无符号的八进制整数。
•s显示一个字符串。
•x显示无符号的十六进制整数。
10至15以a至f表示。
•X显示无符号的十六进制整数。
10至15以A至F表示。
•%它并不是真正的格式控制字符,%%将显示%。
当你使用这些格式控制字符时,你可以在控制字符前给出数字,以表示你将用的几位或几
个字符。
例如,6d表示一个整数有6位。
再请看下面的例子:
{printf"%5sworksfor%5sandearns%2danhour",$1,$2,$3}
将会产生类似如下的输出:
JoeworksforMikeandearns12anhour
当处理数据时,你可以指定数据的精确位数
{printf"%5searns$%.2fanhour",$3,$6}
其输出将类似于:
Joeearns$12.17anhour
你也可以使用一些换码控制符格式化整行的输出。
之所以叫做换码控制符,是因为gawk对
这些符号有特殊的解释。
下面列出常用的换码控制符:
\a警告或响铃字符。
\b后退一格。
\f换页。
\n换行。
\r回车。
\tTab。
\v垂直的tab。
6.9改变字段分隔符
在gawk中,缺省的字段分隔符一般是空格符或TAB。
但你可以在命令行使用-F选项改变字
符分隔符,只需在-F后面跟着你想用的分隔符即可。
gawk-F";"'/tparker/{print}'/etc/passwd
在此例中,你将字符分隔符设置成分号。
注意:
-F必须是大写的,而且必须在第一个引号
之前。
6.10元字符
gawk语言在格式匹配时有其特殊的规则。
例如,cat能够和记录中任何位置有这三个字符
的字段匹配。
但有时你需要一些更为特殊的匹配。
如果你想让cat只和concatenate匹配,则需要
在格式两端加上空格:
/cat/{print}
再例如,你希望既和cat又和CAT匹配,则可以使用或(|):
/cat|CAT/{print}
在gawk中,有几个字符有特殊意义。
下面列出可以用在gawk格式中的这些字符:
•^表示字段的开始。
例如:
$3~/^b/
如果第三个字段以字符b开始,则匹配。
•$表示字段的结束。
例如:
$3~/b$/
如果第三个字段以字符b结束,则匹配。
•.表示和任何单字符m匹配。
例如:
$3~/i.m/
如果第三个字段有字符i,则匹配。
•|表示“或”。
例如:
/cat|CAT/
和cat或CAT字符匹配。
•*表示字符的零到多次重复。
例如:
/UNI*X/
和UNX、UNIX、UNIIX、UNIIIX等匹配。
•+表示字符的一次到多次重复。
例如:
/UNI+X/
和UNIX、UNIIX等匹配。
•\{a,b\}表示字符a次到b次之间的重复。
例如:
/UNI\{1,3\}X
和UNIX、UNIIX和UNIIIX匹配。
•?
表示字符零次和一次的重复。
例如:
/UNI?
X/
和UNX和UNIX匹配。
•[]表示字符的范围。
例如:
/I[BDG]M/
和IBM、IDM和IGM匹配
•[^]表示不在[]中的字符。
例如:
/I[^DE]M/
和所有的以I开始、M结束的包括三个字符的字符串匹配,除了IDM和IEM之外。
6.11调用gawk程序
当需要很多对模式和动作时,你可以编写一个gawk程序(也叫做gawk脚本)。
在gawk程序
中,你可以省略模式和动作两边的引号,因为在gawk程序中,模式和动作从哪开始和从哪结
束时是很显然的。
你可以使用如下命令调用gawk程序:
gawk-fscript.filename
此命令使gawk对文件filename执行名为script的gawk程序。
如果你不希望使用缺省的字段分隔符,你可以在f选项后面跟着F选项指定新的字段分隔符
(当然你也可以在gawk程序中指定),例如,使用分号作为字段分隔符:
gawk-fscript.-F";"filename
如果希望gawk程序处理多个文件,则把各个文件名罗列其后:
gawk-fscript.filename1filename2filename3...
缺省情况下,gawk的输出将送往屏幕。
但你可以使用Linux的重定向命令使gawk的输出送
往一个文件:
gawk-fscript.filename>save_file
6.12BEGIN和END
有两个特殊的模式在gawk中非常有用。
BEGIN模式用来指明gawk开始处理一个文件之前执行一些动作。
BEGIN经常用来初始化数值,设置参数等。
END模式用来在文件处理完成后
执行一些指令,一般用作总结或注释。
BEGIN和END中所有要执行的指令都应该用花括号括起来。
BEGIN和END必须使用大写。
请看下面的例子:
BEGIN{print"Startingtheprocessthefile"}
$1=="UNIX"{print}
$2>10{printf"Thislinehasavalueof%d",$2}
END{print"Finishedprocessingthefile.Bye!
"}
此程序中,先显示一条信息:
Startingtheprocessthefile,然后将所有第一个字段等于
UNIX的整条记录显示出来,然后再显示第二个字段大于10的记录,最后显示信息:
Finished
processingthefile.Bye!
。
6.13变量
在gawk中,可以用等号(=)给一个变量赋值:
var1=10
在gawk中,你不必事先声明变量类型。
请看下面的例子:
$1=="Plastic"{count=count+1}
如果第一个字段是Plastic,则count的值加1。
在此之前,我们应当给count赋予过初值,一
般是在BEGIN部分。
下面是比较完整的例子:
BEGIN{count=0}
$5=="UNIX"{count=count+1}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- awk 详解