如何计算文件中不同字符的数量?

Mne*_*nth 22 command-line text-processing files

我需要一个程序,输出文件中不同字符的数量。例子:

> stats testfile
' ': 207
'e': 186
'n': 102
Run Code Online (Sandbox Code Playgroud)

存在任何工具,可以做到这一点吗?

Ste*_*n D 23

以下应该工作:

$ sed 's/\(.\)/\1\n/g' text.txt | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)

首先,我们在每个字符后插入一个换行符,将每个字符放在自己的行中。然后我们排序。然后我们使用 uniq 命令删除重复项,在每一行前面加上该字符出现的次数。

要按频率对列表进行排序,请将其全部放入sort -nr.

  • 在 Mac OS X 的 sed 上它是 `sed 's/\(.\)/\1\'$'\n/g' text.txt` (4认同)

Gil*_*il' 15

史蒂文的解决方案很好,很简单。由于排序步骤,它对于非常大的文件(不适合大约一半 RAM 的文件)的性能不是很好。这是一个 awk 版本。它也有点复杂,因为它试图为一些特殊字符(换行符、'\:)做正确的事情。

awk '
  {for (i=1; i<=length; i++) ++c[substr($0,i,1)]; ++c[RS]}
  function chr (x) {return x=="\n" ? "\\n" : x==":" ? "\\072" :
                           x=="\\" || x=="'\''" ? "\\" x : x}
  END {for (x in c) printf "'\''%s'\'': %d\n", chr(x), c[x]}
' | sort -t : -k 2 -r | sed 's/\\072/:/'
Run Code Online (Sandbox Code Playgroud)

这是基于相同原理的 Perl 解决方案。Perl 的优点是能够在内部进行排序。如果文件不以换行符结尾,这也不会正确计算额外的换行符。

perl -ne '
  ++$c{$_} foreach split //;
  END { printf "'\''%s'\'': %d\n", /[\\'\'']/ ? "\\$_" : /./ ? $_ : "\\n", $c{$_}
        foreach (sort {$c{$b} <=> $c{$a}} keys %c) }'
Run Code Online (Sandbox Code Playgroud)