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

16

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

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

Existe alguma ferramenta que faz isso?

    
por Mnementh 19.12.2010 / 18:35

2 respostas

17

Os seguintes itens devem funcionar:

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

Primeiro, inserimos uma nova linha depois de cada personagem, colocando cada personagem 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 desse caractere.

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

    
por 19.12.2010 / 18:44
14

A solução de Steven é boa, simples. Não é tão eficaz para arquivos muito grandes (arquivos que não cabem confortavelmente em cerca de metade da sua 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. O Perl tem a vantagem de poder ordenar internamente. Além disso, isso não contará corretamente uma nova linha extra se o arquivo não terminar em 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) }'
    
por 19.12.2010 / 19:17