如何使用 shell 计算一个单词在文件中出现的次数?

How to count the times a word appears in a file using a shell?

给定一个包含文本的文件,我想计算一个字符串的出现次数 "ABCDXYZ" ?

$ cat file.txt 
foo
bar 
foo
bar
baz
baz
bug
bat
foo
bar
so 
on 
and
so 
on
foo

让我们数数 foo

很多时候我看到有人用下面的方式来统计字数:

$ grep -o 'foo' file.txt | wc -l

这里有几个例子:1, 2, 3 and even this youtube video
这确实是一种糟糕的方式,原因如下:

  1. 这表明你从未读过 man grep BSD grep (NetBSD, OpenBSD, FreeBSD) or GNU grep
  2. 所有这些实现都为您提供了计数的选项 -c。 NetBSD 手册页非常清楚地描述了这个选项:
   -c, --count
          Suppress  normal output; instead print a count of matching lines
          for each input file.  With the -v,  --invert-match  option  (see
          below), count non-matching lines.

你可以只使用一个命令:

 $ grep foo -c file.txt 

您不仅可以,而且应该,这样您就可以通过阅读手册页和了解您手头的工具来节省大量的搜索时间!

速度加成 您还可以使 grep 更快,因为管道非常昂贵。 与使用选项 -c:

相比,管道上方显示的短文件的速度要慢 2 倍
$ time grep foo -c file.txt 
4

real    0m0.001s
user    0m0.000s
sys 0m0.001s
$ time grep -o 'foo' file.txt | wc -l
4

real    0m0.002s
user    0m0.000s
sys 0m0.003s

对于大文件,这可能更为重要。这里我把我的文件复制了十万次大一次:

$ for i in `seq 1 300000`; do cat file.txt >> largefile.txt; done
^C
$ wc -l largefile.txt 
1111744 largefile.txt

下面是使用管道的速度:

$ time grep -o foo largefile.txt | wc -l
277936

real    0m0.216s
user    0m0.214s
sys 0m0.010s

下面是仅使用 grep 的速度:

 $ time grep -c foo largefile.txt 
277936

real    0m0.032s
user    0m0.028s
sys 0m0.004s

这些基准测试是在具有 Core i5 和大量 RAM 的机器上完成的,在具有很少 RAM 和 CPU 资源的嵌入式设备上会很明显。

总而言之,不要在不需要的地方使用管道。 UNIX 工具通常具有重叠的功能。了解您的工具,阅读如何使用它们!

要计算一个单词在文件中的出现次数,只需使用:

$ grep -c <word> <filename>

如果要概括计算 all 个单词,请使用:

sort file.txt | uniq -c