一、问题
写一个文本处理程序,查找文本中n个出现频率最高的单词,输出结果需要显示单词出现的次数,并按照次数从大到小排序。高级语言编写这样的程序比较复杂,但shell脚本相对简单。解决这种复杂的问题常用方法是将问题切分成若干简单的子问题加以解决,将查找文本中n个出现频率最高的单词这一问题分为以下几步:一、将文本文件以一行一个单词的形式显示出来;二、将单词中的大写字母转化成小写字母,即Word和word认为一个单词;三、对单词进行排序;四、对排序好的单词列表统计每个单词出现的次数;五、最后显示单词列表的前n项。
二、解决
1、shell脚本
利用管道组成的一条命令:
#查找文本中n个出现频率最高的单词
#!/bin/bash
count=$1 #$1是输出频率最高单词的个数
cat $2 | #$2是目标文本文件名称也可是是字符串
tr -cs "[a-z][A-Z][0-9]" "\n" | #tr是sed的简化,-c用前字符串中字符集的补集替换成后字符串即将不是字符和数字的单词替换换行
#-s删除所有重复出现换行,只保留第一个
#可以写成tr -cs "[a-z][A-Z][0-9]" "\012"或tr -cs "[a-z][A-Z][0-9]" "[\012*]"
tr A-Z a-z | #将大写字母换化为小写字母
sort | #对单词进行排序
uniq -c | #删除文本文件中重复出现的行,-c在每列旁边显示该行重复出现的次数
sort -k1nr -k2 | #字符串以空格分成域,先按第一个域排序,在按第二个域排序
#-k1指定第一个域,-n按数字大写排序,-r排序结果逆向显示
head -n $count #显示前n行
调用脚本./findword.sh 5 filename,其中第一个参数是显示查找的行数,第二个参数是统计单词频率的目标文件。
2、执行
为便于理解可在shell命令行下将管道分解,依次执行echo "tai Yang gao Tai tAi yang 345" | tr -cs "[a-z][A-Z][0-9]" "\n",然后依次加上后面的管道命令,以助于查看结果,分析shell命令。
三、总结
(1)sort -k2第二个域会按字母顺序对单词进行排序,字母以a开头的单词在以z开头的单词后面。
(2)上述一条简单的命令综合应用了tr、sort、uniq、head等文本处理命令,显示shell工具在文本处理方面的强大。