使用命令行打印唯一单词的数量

使用命令行打印唯一单词的数量

我有一些作业:

找出文件 alice 中有多少个唯一单词及其计数?将排序后的唯一单词打印到名为 alice_unique 的文件中。请注意,当您用撇号分割单词时,它们会正确分割,与任何其他特殊字符相同。

到目前为止我有这个

tr -sc 'A-Za-z' '\012' < alice | sort | uniq -c > alice_unique

但我不知道如何将带有特殊字符(',!,?等)的单词放在一起。或者如何计算唯一单词的总数。

文本文件爱丽丝(开头)

爱丽丝梦游仙境

刘易斯·卡罗尔

千年支点3.0版

第一章 掉进兔子洞

爱丽丝开始厌倦了坐在岸边姐姐身边,无所事事:有一两次她偷看了姐姐正在读的书,但里面没有图片或对话,“还有什么?”爱丽丝想,“这就是一本书的用途,没有图片或对话吗?”

所以她在心里思考(尽她所能,因为炎热的天气让她感到非常困倦和愚蠢),制作菊花链的乐趣是否值得费力起床采摘雏菊,突然,一只粉红色眼睛的白兔从她身边跑过来。

答案1

<alice tr -cd "[:alpha:][:space:]-'" |
  tr ' [:upper:]' '\n[:lower:]' |
  tr -s '\n' |
  sed "s/^['-]*//;s/['-]$//" |
  sort |
  uniq -c > alice_unique

逐行:

  • 删除除字母、空格、撇号和连字符之外的所有内容
  • 将空格转换为换行符并将大写转换为小写
  • “挤压”连续换行符
  • 去掉前导或尾随撇号和连字符
  • 对单词进行排序
  • 显示每个唯一单词及其出现次数

如果你应该把数字算作单词,这是错误的。如果文本不是 ASCII,这可能不起作用。为了爱丽丝漫游仙境这可能已经足够好了。

答案2

试试这个,文本文件在哪里:

awk -- '{for (i = 1; i <= NF; i++) wc[$i] += 1}; END {for (w in wc) print w, wc[w]}' <file> | sort

默认情况下,awk 按空格分割每一行输入,生成字段 $1、$2、...,直至 NF,它提供输入字段数量的计数。它还隐式地迭代所有输入行。 END 标记给出了在处理完所有行后要执行的代码块。变量没有声明,方括号用于引用关联数组。

该 awk 程序获取每行的每个单词,使用该单词作为 wc[] 的索引,并添加到计数(如果尚未定义,则将其视为零)。因此,for 循环和所有行上的隐式外部循环都会对所有唯一单词进行计数(标点符号将导致它被计为不同的单词,但如果需要,这很容易修复)。然后 END 块打印出所有单词及其计数。

我使用管道进行排序以按顺序排列单词,而不是使 awk 程序复杂化。我还删除了之前的“-u”,因为每一行都是唯一的。

答案3

以下是AWK的解决方案。请注意,这是一个基本解决方案,可能需要扩展。例如,如果我们解析圣经,我们需要从单词中排除经文。

{
    if (NR == 1) { 
        sub(/^\xef\xbb\xbf/,"")
    }

    gsub(/[,;!()*:?.]*/, "")
    
    for (i = 1; i <= NF; i++) {

        w = $i
        words[w]++
    }
} 

END {

    print length(words)
}

该程序会删除 BOM 字符,如果不这样做,就会使一个单词“唯一”。它去掉了一些基本的标点符号。在 for 循环中,我们对所有字段进行计数。

最后,我们得到了数组的长度。

相关内容