awk详解.docx

上传人:b****6 文档编号:7755081 上传时间:2023-01-26 格式:DOCX 页数:21 大小:26.12KB
下载 相关 举报
awk详解.docx_第1页
第1页 / 共21页
awk详解.docx_第2页
第2页 / 共21页
awk详解.docx_第3页
第3页 / 共21页
awk详解.docx_第4页
第4页 / 共21页
awk详解.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

awk详解.docx

《awk详解.docx》由会员分享,可在线阅读,更多相关《awk详解.docx(21页珍藏版)》请在冰豆网上搜索。

awk详解.docx

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}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1