本节将示范一个统计上班到达时间及迟到次数的程序。
这程序每日被执行时将读入两个数据文件:
* 员工当日到班时间的数据文件 ( 如下列的 arr.dat )
* 存放员工当月迟到累计次数的文件
当程序执行执完毕后将更新第二个数据文件的数据(迟到次数),并打印当日的报表。这程序将分成下列数小节逐步完成,其大纲如下:
7.1 在到班资料文件 arr.dat 之前增加一行抬头"ID Number Arrvial Time",并产生报表输出到文件today_rpt1 中。
<在awk中如何将数据输出到文件>
7.2 将 today_rpt1 上的数据按员工代号排序,并加注执行当日日期;产生文件 today_rpt2
<awk中如何运用系统资源及awk中Pipe的特性>
7.3 将awk程序包含在一个shell script文件中
7.4 于 today_rpt2 每日报表上,迟到者之前加上"*",并加注当日平均到班时间;产生文件 today_rpt3
7.5 从文件中读取当月迟到次数,并根据当日出勤状况更新迟到累计数。
<使用者在awk中如何读取文件数据>
某公司其员工到勤时间文件内容如下,取名为 arr.dat。文件中第一栏为员工代号,第二栏为到达时间。本范例中,将使用该文件为数据文件。
7.1 重定向输出到文件
awk中并未提供如 C 语言中的fopen() 指令,也没有fprintf() 文件输出这样的指令。但awk中任何输出函数之后皆可借助使用与UNIX 中类似的 I/O 重定向符,将输出的数据重定向到指定的文件;其符号仍为 > (输出到一个新产生的文件) 或 >> ( 添加输出的数据到文件末尾 )。
例:在到班数据文件 arr.dat 之前增加一行抬头如下:"ID Number Arrival Time",并产生报表输出到文件 today_rpt1中。
建立如下文件并取名为reformat1.awk
BEGIN { print " ID Number Arrival Time" > "today_rpt1" print "===========================" > "today_rpt1" } { printf(" %s %s\n", $1,$2 ) > "today_rpt1" }
执行:
$ awk -f reformat1.awk arr.dat
执行后将产生文件 today_rpt1,其内容如下:
说 明:
1. awk程序中,文件名称 today_rpt1 的前后须以" (双引号)括住,表示 today_rpt1 为一字符串常量。若未以"括住,则 today_rpt1 将被awk解释为一个变量名称。
在awk中任何变量使用之前,并不须事先声明。其初始值为空字符串(Null string) 或 0。因此程序中若未以 " 将 today_rpt1 括住,则 today_rpt1 将是一变量,其值将是空字符串,这会在执行时造成错误(Unix 无法帮您开启一个以空字符串为文件名的文件)。
因此在编辑awk程序时,须格外留心。因为若敲错变量名称,awk在编译程序时会认为是一新的变量,并不会察觉。因此往往会造成运行时错误。
2. BEGIN 为awk的保留字,是 Pattern 的一种。
以 BEGIN 为 Pattern 的 Actions 于awk程序刚被执行尚未读取数据文件时被执行一次,此后便不再被执行。
3. 读者或许觉得本程序中的I/O重定向符号应使用 " >>" (append)而非 " >"。
本程序中若使用 ">" 将数据重定向到 today_rpt1,awk 第一次执行该指令时会产生一个新文件 today_rpt1,其后再执行该指令时则把数据追加到today_rpt1文件末,并非每执行一次就重开一个新文件。
若采用">>"其差异仅在第一次执行该指令时,若已存在today_rpt1则 awk 将直接把数据append在原文件的末尾。
这一点,与UNIX中的用法不同。