it-swarm-pt.com

Como posso contar o número de caracteres diferentes em um arquivo?

Eu precisaria de um programa que gerasse o número de caracteres diferentes em um arquivo. Exemplo:

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

Existe alguma ferramenta, que faça isso?

19
Mnementh

O seguinte deve funcionar:

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

Primeiro, inserimos uma nova linha após cada caractere, colocando cada caractere em sua própria linha. Então nós classificamos. Em seguida, usamos o comando uniq para remover as duplicatas, prefixando cada linha com o número de ocorrências daquele caractere.

Para classificar a lista por frequência, canalize tudo para sort -nr.

20
Steven D

A solução de Steven é boa e simples. Não tem um desempenho tão bom para arquivos muito grandes (arquivos que não cabem confortavelmente na metade da RAM) por causa da etapa de classificação. Aqui está uma versão do awk. Também é um pouco mais complicado porque tenta fazer a coisa certa para alguns caracteres especiais (novas linhas, ', \, :).

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/:/'

Aqui está uma solução Perl no mesmo princípio. Perl tem a vantagem de poder classificar internamente. Além disso, isso não contará corretamente uma nova linha extra se o arquivo não terminar com um caractere de nova linha.

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

Uma versão lenta, mas relativamente amigável à memória, usando Ruby. Cerca de uma dúzia de MB de RAM, independentemente do tamanho da entrada.

# 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
1
Jared Beck