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


19

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

> stats testfile
' ': 207
'e': 186
'n': 102

存在任何工具,可以这样做吗?

Answers:


21

以下应该工作:

$ sed 's/\(.\)/\1\n/g' text.txt | sort | uniq -c

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

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


4
在Mac OS X的sed上sed 's/\(.\)/\1\'$'\n/g' text.txt
mb21 2013年

非常好,但是很遗憾,如果文本包含Unicode(utf8)字符,它将无法正常工作。可能有办法sed做到这一点,但是Jacob Vlijm的Python解决方案对我来说效果很好。
bitinerant

14

史蒂文的解决方案是一个很好的简单解决方案。由于排序步骤,对于非常大的文件(大约一半的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/:/'

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

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

1
+1不这样做那个可怕的排序
SPARR

1

使用ruby的缓慢但相对友好的版本。不管输入大小如何,大约有十几MB的RAM。

# count.rb
ARGF.
  each_char.
  each_with_object({}) {|e,a| a[e] ||= 0; a[e] += 1}.
  each {|i| puts i.join("\t")}

ruby count.rb < input.txt
t       20721
d       20628
S       20844
k       20930
h       20783
... etc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.