脚本语言AWKWord文档格式.docx
- 文档编号:18650704
- 上传时间:2022-12-30
- 格式:DOCX
- 页数:38
- 大小:35.98KB
脚本语言AWKWord文档格式.docx
《脚本语言AWKWord文档格式.docx》由会员分享,可在线阅读,更多相关《脚本语言AWKWord文档格式.docx(38页珍藏版)》请在冰豆网上搜索。
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中使用"
+"
形容其前方的字符可出现一次或一次以上.故"
[
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 脚本语言 AWK