SHELL篇 统计词频

题目:

写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。

为了简单起见,你可以假设:

    words.txt只包括小写字母和 ' ' 。
    每个单词只由小写字母组成。
    单词间由一个或多个空格字符分隔。

示例:

假设 words.txt 内容如下:

the day is sunny the the
the sunny is is

你的脚本应当输出(以词频降序排列):

the 4
is 3
sunny 2
day 1

说明:

    不要担心词频相同的单词的排序问题,每个单词出现的频率都是唯一的。
    你可以使用一行 Unix pipes 实现吗?

解题方法:

awk '{for(n=1;n<=NF;n++){word[$n]++}} END{for(i in word){print i,word[i]}}' words.txt | sort -nr -k2

要看懂上面的解题方法,需要明白的是:

1、awk是个行编辑器,这个相当重要。

2、在awk中,当字符串或者空字符串参与数值运算时,都会被当做0参与运算,比如:

[root@syztoo ~]# awk 'BEGIN{a=""; a=a+1; print a}' test.txt  
1

3、在awk中,当引用数组中一个不存在的元素时,awk会自动创建这个元素,并为其赋值为空字符串,比如:

[root@syztoo ~]# awk 'BEGIN{print arr[a]; arr[a]++; print arr[a]}' test.txt

1
# 第一次引用数组不存在的元素,所以赋值为空字符串;第二次将空字符串当做0参于数值运算,所以打印1

4、在awk中,NF表示按分隔符分隔后的列数,$n表示当前行的第n列内容,所以:

for(n=1;n<=NF;n++){word[$n]++}}
# 表示遍历当前行的每一个字段,同时将字段作为word数组的索引,进行存储,并做累加计算
# 比如行内容为:the sunny is is
# 那么经过上面代码处理后,word数组存储的是:word[the]=1,word[sunny]=1,word[is]=2

5、END { } 表示所有行处理完以后,需要执行的代码块,这里:

END{for(i in word){print i,word[i]}}
# 上面代码是打印数组的索引和数组元素,i为索引,word[i]为元素

6、sort命令:

选项:
-n 表示按数值排序,从小到大
-r 表示反转排序顺序
-k 后面跟一个数字,表示按第几列内容进行排序
-t 指定分隔符,不指明-t时,表示默认按一个空格分隔
发布了85 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42595012/article/details/104049471
今日推荐