使用部分匹配从文件中获取词频

使用部分匹配从文件中获取词频

我有一个像这样的文本文件:

tom
and
jerry
went
to
america
and
england

我想知道每个单词出现的频率。

当我尝试以下命令时

cat test.txt |sort|uniq -c

我得到以下输出

   1 america
   2 and
   1 england
   1 jerry
   1 to
   1 tom
   1 went

但我也需要部分匹配。即to单词 中出现的单词tom。所以我的预期字数to是 2。可以使用unix命令吗?

答案1

这是一种方法,但不是很优雅:

$ sort -u file | while IFS= read -r word; do 
        printf '%s\t%s\n' "$word" "$(grep -cFe "$word" file)"; 
    done
america 1
and 3
england 1
jerry   1
to  2
tom 1
went    1

答案2

一种awk方法:

awk '
  !x {c[$0]; next}
  {for (i in c) if (index($0, i)) c[i]++}
  END{for (i in c) print c[i]"\t"i}' file x=1 file | sort -k1rn

您的输入给出了哪些

3       and
2       to
1       america
1       england
1       jerry
1       tom
1       went

我们分两遍处理输入。在第一遍中,我们将不同单词的列表记录为c哈希表的键。

在第二遍中,对于文件中的每一行,我们循环遍历所有键,c如果在该行中找到该键,则增加相应的值。

文件中不同单词的列表最终存储在内存中。如果这些是英语单词,那应该不成问题,因为英语中的不同单词只有不到 200,000 个。

答案3

这不会使系统崩溃,但可能需要很长时间才能运行,因为它会多次解析输入。假设输入文件名为“in”:

sort -u < in | while read w
do
    printf "%d\t%s\n" `grep -c "$w" in` "$w"
done

你的输入让我:

1       america
3       and
1       england
1       jerry
2       to
1       tom
1       went

答案4

我不清楚部分匹配是否要锚定到行的开头。假设答案是肯定的,那么什么可能这里加快速度的是通过古老的命令使用二分搜索look。当然look需要对其输入文件进行排序。因此,首先创建原始文件的排序版本

 sort file > file.sorted

然后循环遍历原始文件,look一次根据排序后的文件查找一个单词。

while read -r word; do 
    printf "%s %d\n" "$word" "$(look -b "$word" file.sorted | wc -l)"; 
done <file

有些系统不需要-b传递标志来look强制进行二分搜索。排序文件的磁盘缓存可以帮助进一步加快速度

相关内容