继续前面两节的内容,我们来看下面修改后的、加了注释的脚本:
#!/bin/bash
ls -l
$* | awk ‘
/* filesum: 列出文件总的字节数*/
/* 输入:由命令"ls -l"生成的长列表*/
/*#1 输出列的标题*/
BEGIN { print "BYTES", "\t", "FILE" }
/*#2 测试第9个字段,文件以"-"开始*/
NF == 9 && /^-/ {
sum += $5 /*累计文件大小*/
++filenum /*系统文件个数*/
print $5,"\t",$9 /*打印大小和文件名*/
/*#3 测试第9个字段,目录由"d"开始*/
NF == 9 && /^d/ {
print "<dir>", "\t", $9 # print <dir> and name
/*#4 测试ls -lR line ./dir:*/
$1 ~ /^\..*:$/ {
print "\t" $0 /*打印用制表符处理的行*/
/*#5 所有工作已完*/
END {
/*打印所有文件总的大小和文件数目*/
print "Total: ", sum, "bytes (" filenum " files)"
}‘
这里对规则以及与之相关的操作设置了编号,以便进行讨论。由ls -l产生的列表包含文件的9个字段。awk在系统变量NF中给出了一个记录中的字段的个数。因此,规则2和规则3测试NF是否等于9。这可以使我们避免与奇数空行或表示块总量的行匹配。因为我们希望对目录和文件做不同的处理,所以我们使用另一个模式来匹配行的第一个字符。在规则2中我们测试行的第一个位置的字符"-",这表示一个文件。如果匹配则递增与之相关的文件计数器并累计文件的大小。在规则3中我们测试一个目录,用"d"作为第一个字符来表示。相关的操作是在文件大小的位置上打印<dir>。规则2和规则3是结合表达式,用&&操作符将两个模式结合起来。两个模式都必须匹配表达式的值才为真。
规则4用于测试由ls -lR产生的列表的特殊形式( "./old;" )。我们可以使用正则表达式或关系表达式来编写一些匹配这一行的模式。
awk使用匹配操作符(~)来测试第一个字段是否匹配一个正则表达式。相关的操作只由一个print语句组成。
规则5是END模式,它的操作只被执行一次,用于打印出文件总的尺寸和数量。
程序filesum演示了awk中的许多基本的结构。更重要的是,它提供了如何编写程序的一个很好的思路。如果想修改以上程序,可以为目录增加一个计数器。
参考资料:http://www.linuxawk.com/communication/521.html