Bash Shell汇总数字列表

Bash Shell汇总数字列表,你需要汇总数字列表,其中有些数字并未出现在行中。

解决方案

用 awk 先过滤出待汇总的字段,然后再做汇总。这里我们要对 ls -l 命令输出的文件大小进行汇总。

ls -l | awk '{sum += $5}; END {print sum}'

讨论

我们要汇总 ls -l 输出的第 5 个字段。ls -l 的输出如下所示:

-rw-r--r-- 1 albing users 267 2005-09-26 21:26 lilmax

各个字段分别为:权限、链接、所有者、所属组、大小(以字节为单位)、最后一次修改日期、最后一次修改时间,以及文件名。我们只对文件大小感兴趣,因此在 awk 程序中用 $5 来引用该字段。

我们在花括号({})里放置了两段 awk 代码,注意,awk 程序中可以有多个代码段(或代码块)。前有关键词 END 的代码块仅在程序其他部分完成后运行一次。同样,你可以在代码块前添加 BEGIN 关键词并提供读取输入前运行的代码。BEGIN 代码块可用于初始化变量,这里我们用它来初始化 sum,不过 awk 能够确保变量内容一开始为空。

如果查看 ls -l 命令的输出,你会注意到第一行是文件总量信息 ,与其他行的预期格式不一致。

该行给出了目录下的文件总量,其形式为“total N ”(N 代表具体数量)。

我们有两种处理方法。第一种方法是,假装该行不存在,之前的解决方案用到的就是这个方法。因为用不着的这行并没有第 5 个字段,所以 $5 为空,汇总结果不会受到影响。

更负责的做法,即第二种方法是跳过这一行。将 ls -l 命令的输出传给 awk 之前,先使用 grep。

ls -l | grep -v '^total' | awk '{sum += $5}; END {print sum}'

或者在 awk 中完成类似操作。

ls -l | awk '/^total/{next} {sum += $5}; END {print sum}'

^total 是一个正则表达式,意思是“位于行首的字母 t-o-t-a-l”(开头的 ^ 将搜索锚定在行首)。对于匹配该正则表达式的输入行,执行与之关联的代码块。第二个代码块(sum)前面什么都没有,这意味着 awk 会对所有输入行执行该代码块(不管是否匹配正则表达式)。

针对“total”进行特殊处理的目的是想要将其从汇总过程中排除。因此,在 ^total 对应的代码块中,我们使用了 next 命令,它会停止处理该输入行,并从下一行输入重新开始。因为下一行并不是以“total”起始,所以 awk 将对其执行第二个代码块。我们也可以用 getline 代替 next 命令。getline 并不会重新匹配开头的模式,而是继续往后匹配。注意,在 awk 编程中,代码块的顺序很重要。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!