Por exemplo, eu tenho um arquivo 1.txt
que contém:
Moscow
Astana
Tokyo
Ottawa
Quero contar o número de todos os caracteres como:
a - 4,
b - 0,
c - 1,
...
z - 0
command-line
bash
text-processing
Set-xx
fonte
fonte
Respostas:
Você poderia usar isto:
A
sed
peça coloca uma nova linha após cada caractere. Então nós saímos emsort
ordem alfabética. E finalmenteuniq
conta o número de ocorrências. O-i
sinalizador deuniq
pode ser omitido se você não desejar distinção entre maiúsculas e minúsculas.fonte
sort -k 2
para listá-los alfanumericamente.sed -e $'s/\(.\)/\\1\\\n/g'
(consulte também stackoverflow.com/a/18410122/179014 ) #| sort -rnk 1
. E se você está lidando com arquivos muito grandes, como eu sou, você pode apenas experimentar alguns linha mil para obter um proxy para as contagens reais:cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
Um pouco tarde, mas para concluir o conjunto, outra abordagem python (3), classificou o resultado:
Explicação
Leia o arquivo, pule os espaços e retorne como "caracteres":
Crie um conjunto (classificado) de únicos:
Conte e imprima a ocorrência para cada um dos caracteres:
Como usar
chars_count.py
Execute-o com o arquivo como argumento:
se o script for executável ou:
se não é
fonte
Por padrão em awk o F ield S eparator (FS) é espaço ou guia . Como queremos contar cada caractere, teremos que redefinir o FS para nothing (
FS=""
) para dividir cada caractere em uma linha separada e salvá-lo em uma matriz e, no final doEND{..}
bloco interno , imprima suas ocorrências totais com o seguinte comando awk :No
{for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...
bloco, apenas dividimos os caracteres. E,no
END{for (c in a) print c,a[c]}
bloco, estamos fazendo um loop para organizara
e imprimir os caracteres salvos neleprint c
e seu número de ocorrênciasa[c]
fonte
Faça um
for
loop para todos os caracteres que você deseja contar e usegrep -io
para obter todas as ocorrências do caractere e do caso de ignição, alémwc -l
de contar instâncias e imprimir o resultado.Como isso:
O script gera isso:
EDITAR após o comentário
Para criar um loop para todos os caracteres imprimíveis, você pode fazer isso:
Isso contará todos os caracteres ANSI de 32 a 126 - esses são os mais legíveis. Observe que isso não usa ignorar maiúsculas e minúsculas.
a saída disso será:
fonte
i
do grep. (na sua pergunta você tinha apenas 3 no resultado esperado)grep
toda a entrada repetidamente.Aqui outra solução (em awk) ...
fonte
cat file | awk '...'
: você pode dizer diretamenteawk '...' file
.O
perl
oneliner a seguir fará a contagem. Coloquei o regex no contexto da lista (para obter o número de correspondências) e o coloquei no contexto escalar:fonte
perl -Mfeature=say -e '$a=join("",<>);say join(",\n", map { sprintf("%s - %d", $_, ($d=()=$a=~/$_/gi)); } ("a".."z"))'
Aqui está uma solução usando Python:
Aqui, usamos a classe
collections
do móduloCounter
para contar o número de ocorrências de cada caractere; em seguida, para fins de impressão, usamos ostring
módulo para obter todas as letras minúsculas pela variávelstring.lowercase
.Salve o script acima em um arquivo, com o nome desejado, por exemplo
count.py
. Agora, no mesmo diretório em que o arquivo é salvo, você pode simplesmente executarpython count.py
para executá-lo; em qualquer outro diretório, use o caminho absoluto para o arquivo para executá-lo, ou sejapython /absolute/path/to/count.py
.fonte
Há um tempo atrás, escrevi um programa em C para fazer isso, porque precisava examinar arquivos grandes e produzir algumas estáticas.
compile com (assumindo que o código fonte reside em
character-distribution.c
):correr com:
Se você não possui um compilador C pronto, instale o GCC:
fonte
Solução semelhante ao @heemayl, com código mais rígido, que funciona no Python 2.7 e Python 3.
A primeira afirmação
count = collections.Counter(…)
faz todo o trabalho real.fileinput.input()
lê todas as linhas da entrada, que podem ser canalizadas via stdin ou como argumentos da linha de comando.*
faz com que considere um personagem de cada vez, e não uma linha de cada vez.count = Counter(…)
conta ocorrências de cada caractere de forma eficiente, em uma única passagem e armazena o resultado nacount
variávelA segunda linha apenas imprime os resultados.
'{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase
faz uma lista de cada personagem e sua contagem.print(',\n'.join(…))
coloca no formato desejado: um por linha, separado por vírgulas, mas sem vírgula na última linha.fonte
GNU awk 4.1
Se você possui uma versão anterior do GNU awk, pode usá-lo
for (c in b) print c, b[c]
.fonte
Aqui está a resposta usando ruby. Isso é feito alterando a string para uma lista uniq dos diferentes caracteres e usando o método count em cada um deles.
fonte