脚本语言AWKWord文档格式.docx

上传人:b****6 文档编号:18650704 上传时间:2022-12-30 格式:DOCX 页数:38 大小:35.98KB
下载 相关 举报
脚本语言AWKWord文档格式.docx_第1页
第1页 / 共38页
脚本语言AWKWord文档格式.docx_第2页
第2页 / 共38页
脚本语言AWKWord文档格式.docx_第3页
第3页 / 共38页
脚本语言AWKWord文档格式.docx_第4页
第4页 / 共38页
脚本语言AWKWord文档格式.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

脚本语言AWKWord文档格式.docx

《脚本语言AWKWord文档格式.docx》由会员分享,可在线阅读,更多相关《脚本语言AWKWord文档格式.docx(38页珍藏版)》请在冰豆网上搜索。

脚本语言AWKWord文档格式.docx

FNR当前的处理记号(读入了多少域数据?

OFS输出的字段分隔符,默认为空格

例如:

awk从资料文件emp.dat中读入第一笔数据行:

"

A125Jenny100210"

之后,程序中:

$0之值将是"

$1之值为"

A125"

$2之值为"

Jenny"

$3之值为100

$4之值为210

$NF之值为4

$NR之值为1

$FILENAME之值为"

emp.dat"

7.awk的工作流程:

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

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

2.自动更新(Update)相关的内建变量之值.如:

NF,NR,$0...

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

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

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

8,打印文件中指定的字段数据并加以计算:

awk处理数据时,它会自动从数据文件中一次读取一笔记录,并会将该数据切分成一个个的字段;

程序中可使用$1,$2,...直接取得各个字段的内容.

例:

以文件emp.dat为例,计算每人应发工资并打印报表.

$awk'

{print$2,$3*$4}'

emp.dat

结果:

Jenny21000

Dan23650

Max27170

John27500

Linda19950

执行awk的语法为:

$awk'

awk程序'

欲处理的资料文件文件名

本范例中的程序部分为{print$2,$3*$4}.把程序置于命令行时,程序之前后须以'

括住.print的参数间彼此以"

隔开,印出数据时彼此间会以空白隔开.

将上述的程序部分({print$2,$3*$4})储存于文件pay1.awk中.执行命令时再指定awk程序文件之文件名.这是执行awk的另一种方式,特别适用于程序较大的情况,其语法如下:

$awk-fawk程序文件名数据文件文件名

故执行下列两命令,将产生同样的结果:

$awk-fpay1.awkemp.dat

{print$2,$3*$4}'

读者可使用"

-f"

参数,让awk主程序使用“其它仅含awk函数的文件中的函数”其语法如下:

$awk-fawk主程序文件名-fawk函数文件名数据文件文件名

awk中也提供与C语言中类似用法的printf()函数.用法一样:

编辑另一个awk程序如下,并取名为pay2.awk:

{printf("

%6sWorkhours:

%3dPay:

%5d\n"

$2,$3,$3*$4)}

执行下列命令

$awk-fpay2.awkemp.dat

JennyWorkhours:

100Pay:

21000

DanWorkhours:

110Pay:

23650

MaxWorkhours:

130Pay:

27170

JohnWorkhours:

125Pay:

27500

LindaWorkhours:

 

95Pay:

19950

9.选择符合指定条件的记录:

awk中除了>

<

==,!

=,...等关系运算符(RelationalOperators)外,另外提供~(match),!

~(NotMatch)二个关系运算符.利用这两个运算符,可判断某字符串是否包含能匹配所指定正则表达式的子字符串.

组装部门员工调薪5%,(组装部门员工之ID以"

开头)所有员工最后之薪资率若仍低于100,则以100计:

编写如下之程序,并取名adjust1.awk:

$1~/^A.*/{$3*=1.05}$3<

100{$3=100}

{printf("

%s%8s%d\n"

$1,$2,$3)}

执行下列命令:

$awk-fadjust1.awkemp.dat

A125 

 

Jenny105

A341 

Dan115

P158 

Max130

P148 

John125

A123 

Linda100

说明:

awk的工作程序是:

从数据文件中每次读入一个数据行,依序执行完程序中所有的Pattern{Action}指令:

第一个Pattern{Action}:

$1~/^A.*/{$3*=1.05}

第二个Pattern{Action}:

$3<

100{$3=100}

第三个Pattern{Action}:

$1,$2,$3)} 

再从数据文件中读进下一笔记录继续进行处理.

建立一个数据文件,并取名为reg.dat此为一学生注册的资料文件;

第一栏为学生姓名,气候为该生所修课程。

MaryO.S.Arch.Discrete

SteveD.S.AlgorithmArch.

WangDiscreteGraphicsO.S.

LisaGraphicsA.I.

LilyDiscreteAlgorithm

10.awk中数组的特性:

使用字符串当数组的下标(index).

使用数组前不须宣告数组名及其大小.

希望用数组来记录reg.dat中各门课程的修课人数:

有2个学生修"

O.S."

则以Number["

]=2表之.

若修"

的人数增加一人,则Number["

]=Number["

]+1或Number["

]++.

11.取出数组中存储的信息:

awk提供了一个指令,藉由该指令awk会自动找寻数组中使用过的所有下标.使用该指令时,须指定所要找寻的数组,及一个变量.awk会使用该的变量来记录从数组中找到的每一个下标.

for(courseinNumber){....}

指定用course来记录awk从Number[]中所找到的下标.awk每找到一个下标时,就用course记录该下标之值且执行{....}中之指令.

统计各科修课人数,并印出结果.

建立如下程序,并取名为course.awk:

{for(i=2;

i<

=NF;

i++)Number[$i]++}

END{for(courseinNumber)printf("

%10s%d\n"

course,Number[course])}

执行下列命令:

$awk-fcourse.awkreg.dat

Graphics2

O.S.2

Discrete3

A.I.1

D.S.1

Arch.2

Algorithm2

Pattern{Actions}指令中END为awk之保留字,为Pattern的一种.END成立(其值为true)的条件是:

awk处理完所有数据,即将离开程序时."

平常读入数据行时,END并不成立,故其后的Actions并不被执行;

唯有当awk读完所有数据时,该Actions才会被执行(注意,不管数据行有多少笔,END仅在最后才成立,故该Actions仅被执行一次.)

BEGIN与END有点类似,是awk中另一个保留的Pattern.唯一不同的是:

以BEGIN为Pattern的Actions于程序一开始执行时,被执行一次."

awk程序中若含有以$开头的自定变量,都将以如下方式解释:

以i=2为例,$i=$2表第二个字段数据.(实际上,$在awk中为一运算符(Operator),用以取得字段数据.)

12.awk程序中使用shell命令:

awk程序中允许呼叫Shell指令.

写一个awk程序来打印出线上人数.

将下列程序建文件,命名为count.awk

BEGIN{

while("

who"

|getline)n++

printn

}

并执行下列命令:

$awk-fcount.awk

显示在线人数.

awk程序并不一定要处理数据文件.以本例而言,仅输入程序文件count.awk,未输入任何数据文件.

BEGIN只在awk开始执行程序,尚未开启任何输入文件前,被执行一次.(注意:

只被执行一次).字符串"

当成Shell上的命令,并将该命令送往Shell执行,执行的结果(原先应于屏幕印出者)则藉由pipe送进awk程序中.

getline为awk所提供的输入指令.其语法如下:

语法由何处读取数据数据读入后置于

getlinevar<

file所指定的file变量var(var省略时,表示置于$0)

getlinevarpipe变量变量var(var省略时,表示置于$0)

getlinevar见注一变量var(var省略时,表示置于$0)

注:

当Pattern为BEGIN或END时,getline将由stdin读取数据,否则由awk正处理的数据文件上读取数据.

getline一次读取一行数据,若读取成功则return1,若读取失败则return-1,若遇到文件结束(EOF),则return0;

本程序使用getline所return的数据来做为while判断循环停止的条件,某些awk版本较旧,并不容许使用者改变$0之值.这种版的awk执行本程序时会产生Error,读者可于getline之后置上一个变量(如此,getline读进来的数据便不会被置于$0),或直接改用gawk便可解决.

awk程序应用实例:

本节将示范一个统计上班到达时间及迟到次数的程序.这程序每日被执行时将读入二个文件:

员工当日到班时间的数据文件(如下列之arr.dat)

存放员工当月迟到累计次数的文件.

当程序执行执完毕后将更新第二个文件的数据(迟到次数),并打印当日的报表.这程序将分成下列数小节逐步完成,其大纲如下:

(1)在到班资料文件arr.dat之前增加一行抬头"

IDNumberArrvialTime"

并产生报表输出到文件today_rpt1中.

(2)将today_rpt1上的数据按员工代号排序,并加注执行当日日期;

产生文件today_rpt2.

(3)将awk程序包含在一个shellscript文件中.

(4)于today_rpt2每日报表上,迟到者之前加上"

*"

并加注当日平均到班时间;

产生文件today_rpt3.

(5)从文件中读取当月迟到次数,并根据当日出勤状况更新迟到累计数.

某公司其员工到勤时间档如下,取名为arr.dat.文件中第一栏为员工代号,第二栏为到达时间.本范例中,将使用该文件为数据文件.

10347:

26

10257:

27

11017:

32

10067:

45

10127:

46

10287:

49

10517:

51

10297:

57

10427:

59

10088:

01

10528:

05

10058:

12

13.重定向输出到文件:

>

(输出到一个新产生的文件)或>

(添加输出的数据到文件末尾).

在到班数据文件arr.dat之前增加一行抬头"

IDNumberArrivalTime"

并产生报表输出到文件today_rpt1中.

建立如下文件并取名为reformat1.awk:

BEGIN{print"

IDNumberArrivalTime"

>

"

today_rpt1"

print"

==========================="

%s%s\n"

$1,$2)>

}

执行:

$awk-freformat1.awkarr.dat

将产生文件today_rpt1,其内容如下:

IDNumberArrivalTime

============================

awk程序中,文件名称today_rpt1的前后须以"

括住,表示today_rpt1为一字符串常量.若未以"

括住,则today_rpt1将被awk解释为一个变量名称.

在awk中任何变量使用之前,并不须事先声明.其初始值为空字符串(Nullstring)或0.因此程序中若未以"

将today_rpt1括住,则today_rpt1将是一变量,其值将是空字符串,这会在执行时造成错误.

14.awk中利用系统资源:

将数据按员工ID排序后再输出到文件today_rpt2,并于表头附加执行时的日期.

分析:

awk程序中pipe可接受下列两种语法:

(1)awkoutput指令|"

Shell接受的命令"

(如:

print$1,$2|"

sort-k1"

(2)"

|awkinput指令 

(如:

ls"

|getline).

awkinput指令只有getline一个.awkoutput指令有print,printf()二个.

(1)语法中,awk所输出的数据将转送往Shell,由Shell的命令进行处理.以上例而言,print所输出的数据将经由Shell命令"

排序后再送往屏幕(stdout).

上列awk程序中,"

print$1,$2"

可能反复执行很多次,其输出的结果将先暂存于pipe中,等到该程序结束时,才会一并进行"

不论print$1,$2被执行几次,"

的执行时间是"

awk程序结束时"

的执行次数是"

一次"

(2)语法中,awk将先调用Shell命令.其执行结果将通过pipe送入awk程序,以上例而言,awk先让Shell执行"

Shell执行后将结果存于pipe,awk指令getline再从pipe中读取数据.

awk"

立刻"

调用Shell来执行"

执行次数是一次.getline则可能执行多次(若pipe中存在多行数据).

建立如下文件并取名为reformat2.awk:

#程序reformat2.awk

#这程序用以练习awk中的pipe

date"

|getline#Shell执行"

.getline取得结果并以$0记录

Todayis"

$2,$3>

today_rpt2"

========================="

close("

{printf("

%s%s\n"

$1,$2)|"

sort-k1>

执行如下命令:

$awk-freformat2.awkarr.dat

执行后,系统会自动将sort后的数据追加到文件today_rpt2末端.

Todayis 

09月21日

=========================

awk提供另一个调用Shell命令的方法,即使用awk函数system("

shell命令"

)例如:

BEGIN{

system("

date>

date.dat"

getline<

date.dat"

Todayis"

$2,$3

但使用system("

shell命令"

)时,awk无法直接将执行中的部分数据输出给Shell命令.且Shell命令执行的结果也无法直接输入到awk中(可采用中间文件存储).

15.执行awk程序:

将awk程序直接写在shellscript之中.此后使用者执行awk程序时,就不需要每次都键入"

awk-fprogramdatafile"

建立一个简单的awk程序mydump.awk,如下:

{print}

print之后未接任何参数时,表示"

print$0"

若欲执行该awk程序,来印出文件today_rpt1及today_rpt2的内容时,执行下列命令:

方式一:

awk-fmydump.awktoday_rpt1today_rpt2

方式二:

awk'

{print}'

today_rpt1today_rpt2第二种方式系将awk程序直接写在Shell的命令行上,这种方式仅适合较短的awk程序.

方式三:

建立如下之shellscript,并取名为mydisplay:

#!

/bin/sh

#注意以下的awk与'

之间须有空白隔开

'

$*

#注意以上的'

与$*之间须有空白隔开

执行mydisplay之前,须先将它改成可执行的文件(此步骤往后不再赘述).请执行如下命令:

$chmod+xmydispaly

往后使用者就可直接把mydisplay当成指令,来display任何文件,例如:

$./mydisplaytoday_rpt1today_rpt2

在script文件mydisplay中,指令"

与第一个'

之间须有空格(Shell中并无"

awk'

指令).

第一个'

用以通知Shell其后为awk程序.第二个'

则表示awk程序结束.故awk程序中一律以"

括住字符串或字符,而不使用'

以免Shell混淆.

$*为shellscript中的用法,它可用来代表命令行上"

mydisplay之后的所有参数"

.例如:

$mudisplaytoday_rpt1today_rpt2

事实上Shell已先把该指令转换成:

{print}

today_rpt1today_rpt2

本例中,$*用以代表"

today_rpt1today_rpt2"

.在Shell的语法中,可用$1代表第一个参数,$2代表第二个参数.当不确定命令行上的参数个数时,可使用$*表之.

awk命令行上可同时指定多个数据文件,例如:

$awk-fdump.awktoday_rpt1today_rpt2

某些awk程序"

仅"

包含以BEGIN为Pattern的指令.执行这种awk程序时,awk并不须开启任何数据文件.此时命令行上若指定一个不存在的数据文件,并不会产生"

无法打开文件"

的错误.

awk会将Shell命令行上awk程序(或-f程序文件名)之后的所有字符串,视为将输入awk进行处理的数据文件文件名.

若执行awk的命令行上"

未指定任何数据文件文件名"

则将stdin视为输入之数据来源,直到输入endoffile(Ctrl-D)为止.可利用这个特点,设计可与awk即时聊天的程序.

16.改变awk切割字段的方式及自定义函数:

awk不仅能自动分割字段,也允许使用者改变其字段切割方式以适应各种格式之需要.使用者也可自定义函数,若有需要可将该函数单独写成一个文件,以供其它awk程序调用.

若八点为上班时间,请加注"

于迟到记录之前,并计算平均上班时间.

注:

awk中字符串"

26"

与数字26并无差异,可直接做字符串或数学运算,这是awk重要特色之一.

方法一:

对到达时间($2)d:

dd或dd:

dd进行字符串运算,分别取出到达的小时数及分钟数.

length(字符串):

返回该字符串的长度.

substr(字符串,起始位置,长度):

返回从起始位置起,指定长度之子字符串.若未指定长度,则返回从起始位置到字符串末尾的子字符串. 

则:

小时数=substr($2,1,length($2)-3)

分钟数=substr($2,length($2)-2)

方法二:

字段分隔字符FS(fieldseperator)是awk的内建变量,其默认值是空白及tab.awk每次切割字段时都会先参考FS的内容.若把"

:

也当成分隔字符,则awk便能自动把小时数及分钟数分隔成不同的字段.故令FS="

[\t:

]+"

(注:

]+为一RegularExpression).

RegularExpression中使用中括号[...]表示一个字符集合,用以表示任意一个位于两中括号间的字符.故可用"

]"

表示一个空白,tab或"

.

RegularExpression中使用"

+"

形容其前方的字符可出现一次或一次以上.故"

[

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

当前位置:首页 > 经管营销

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

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