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

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

解决方案

如果使用的是 bash 4.0 或更高版本,那么可以用关联数组(其他语言中也称为散列或字典)来搞定。
在这个例子中,我们要统计系统中的各个用户都拥有多少文件。ls -l 输出的第 3 个字段就是用户名,因此我们用该字段($3)作为数组索引,并增加数组元素。

# 实例文件:cnt_owner
# 使用bash统计文件所有者
# 将“ls -l”的输出通过管道传入该脚本

declare -A AACOUNT
while read  -a LSL
do
    # 只考虑包含7个及以上字段的行
    if (( ${#LSL[*]} > 7 ))         # 数组大小
    then
        NDX=${LSL[3]}               # 字符串赋值
        (( AACOUNT[${NDX}] += 1 ))  # 算术递增
    fi
done

for VALS in "${!AACOUNT[@]}"        # 各个元素的索引
do
    echo $VALS "owns" ${AACOUNT[$VALS]} "files"
done
我们可以像下面这样调用该脚本并获得结果。
$ ls -lR /usr/local | bash cnt_owner.sh
bin owns 68 files
root owns 13755 files
man owns 11491 files
albing owns 1801 files
$

讨论

read -a LSL 每次读取一行,将其中的各个单词(由空白字符分隔)分别赋给数组 LSL 的各元素。通过检查数组大小,我们可以确定读入了多少个单词,以此过滤不包含文件名的那些行。它们属于 ls -lR 输出的一部分,通常是为了提高可读性,因为其中包含分隔不同目录的空行和各个子目录文件总量的统计。对于我们的脚本而言,这都是些无用信息,好在这种行并不像其他行那样包含太多的字段(单词),不难分辨。

只有那些至少有 7 个单词的行,我们才从中提取第 3 个单词(文件所有者)并将其作为关联数组的索引。像 LSL 这样的标准数组,数组元素通过整数索引来引用。对于关联数组,索引可以是字符串。

为了输出结果,我们需要遍历数组索引。${AACOUNT[@]}会生成数组所有元素值的列表,如果加上惊叹号变成 ${!AACOUNT[@]},则得到的是该数组所有索引的列表。

注意,输出并不遵循特定的顺序(这与散列算法的实现有关)。要想按照用户名或文件数量排序,可以通过管道将结果传给 sort 命令。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!