Bash Shell awl统计字符串出现次数

你需要统计多个不同字符串出现的次数,其中包括一些事先不知道具体是什么的字符串。也就是说,你要统计的并不是已经确定好的一组字符串的出现次数。相反,你会在数据中碰到一些未知字符串并对其进行统计。

解决方案

可以用 awk 的关联数组(其他语言中也称为散列或字典)来搞定。

在这个例子中,我们要统计系统中各个用户都拥有多少文件。ls -l 输出的第三个字段就是用户名,因此使用该字段($3)作为数组索引,并增加数组元素。

#!/usr/bin/awk -f
# 实例文件:asar.awk
# Awk关联数组
# 用法:ls -lR /usr/local | asar.awk

NF > 7 {
    user[$3]++
}

END {
    for (i in user) {
        printf "%s owns %d files\n", i, user[i]
    }
}

这里我们调用 awk 的方式有点不一样。由于这个 awk 脚本有些复杂,我们将它放在了单独的文件中。-f 选项告诉 awk 从文件中读取脚本,不过也可以在脚本中使用 shebang 行 #!/usr/bin/awk

shebang 这个词其实是两个字符名称(sharp-bang)的简写。在 Unix 的行话中,用 sharp 或 hash(有时候是 mesh)来称呼字符“#”,用 bang 来称呼惊叹号“!”,因而 shebang 合起来就代表了这两个字符。

$ ls -lR /usr/local | awk -f asar.awk
bin owns 68 files
albing owns 1801 files
root owns 13755 files
man owns 11491 files
$

讨论

我们用条件 NF > 7 来限制执行部分 awk 脚本,以此过滤不包含文件名的那些行,此类行出现在 ls -lR 的输出中是为了提高可读性,其中包括用于分隔不同目录的空行以及每个子目录中的文件总量信息。这种行包含的字段(单词)不多。左花括号前的 NF > 7 并没有出现在斜线中,这表明它并非正则表达式。它其实就是一个条件表达式,和 if 语句中使用的差不多,用于判断条件的真假。NF 是一个特殊的内建变量,其中保存着当前输入行的字段总数。因此,如果某个输入行的字段(单词)数超过了 7 个,则由花括号中的语句进行处理。

最重要的是下面这行。

user[$3]++

这里用户名(如 bin)被用作数组索引。之所以称为关联数组,是因为使用散列表(或类似机制)将每个独一的字符串与数值关联了起来。这些事情已经由 awk 在幕后帮你做好了;字符串比较或查找之类的都不用你操心。

建立好关联数组之后,似乎不那么容易获得数组元素的值了。为此,awk 提供了一种特殊形式的 for 循环。与数字形式的 for(i=0; i<max; i++) 不同,它有专用于关联数组的语法。

for (i in user)

在该语句中,变量 i 连续从数组 user 的索引中获得值(没有什么特定顺序)。在示例中,这意味着 i 在每次循环中都会得到一个值(bin、albing、root、man)。如果以前还没见识过关联数组,希望这次能让你大开眼界,印象深刻。关联数组是 awk(以及 Perl)的一个强大特性。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!