Eu tenho 100 milhões de linhas no meu arquivo.
Cada linha possui apenas uma coluna.
por exemplo
aaaaa
bb
cc
ddddddd
ee
Eu gostaria de listar a contagem de caracteres
Como isso
2 character words - 3
5 character words - 1
7 character words - 1
etc.
Existe alguma maneira fácil de fazer isso no terminal?
text-processing
Giri
fonte
fonte
Respostas:
O primeiro
awk
filtro apenas imprimirá o comprimento de cada linha no arquivo chamadofile
. Estou assumindo que este arquivo contém uma palavra por linha.O
sort -n
(classificar as linhas da saída deawk
numericamente em ordem crescente) euniq -c
(contar o número de vezes que cada linha ocorre consecutivamente) criará a seguinte saída para os dados fornecidos:Isso é analisado pelo segundo
awk
script que interpreta cada linha como "número X de linhas com caracteres Y" e produz a saída desejada.A solução alternativa é fazer tudo isso
awk
e manter contagens de comprimentos em uma matriz. É uma troca entre eficiência, legibilidade / facilidade de entendimento (e, portanto, capacidade de manutenção) de qual solução é a "melhor".Solução alternativa:
fonte
Outra maneira de fazer tudo
awk
sozinhowords[length()]++
use o comprimento da linha de entrada como chave para salvar a contagemEND{for(k in words)print k " character words - " words[k]}
depois que todas as linhas forem processadas, imprima o conteúdo da matriz no formato desejadoComparação de desempenho, os números selecionados são os melhores de duas execuções
Se o arquivo tiver apenas caracteres ASCII,
Não sei por que o tempo para
perl
não mudou muito, provavelmente a codificação deve ser definida de outra maneirafonte
length
sem()
funciona perfeitamente bem aqui, por isso pode ser redundante adicionar chaves. Estou usando o GNU awk, no entanto.In older versions of awk, the length() function could be called without any parentheses. Doing so is considered poor practice, although the 2008 POSIX standard explicitly allows it, to support historical practice. For programs to be maximally portable, always supply the parentheses
Aqui está um
perl
equivalente (com - opcional - classificação):fonte
{$a<=>$b}
depois desort
corrigir isso. Como alternativa, pode-se usar uma matriz normal com teclas numéricas e pular todas as chaves em que o valor é zero / indefinido.Uma alternativa uma chamada para GNU awk, usando printf :
O algoritmo principal apenas coleta as contagens de caracteres em uma matriz. A parte final imprime as contagens coletadas formatadas com printf.
Rápido, simples, uma única chamada para o awk.
Para ser preciso: mais memória é usada para manter a matriz.
Mas nenhuma classificação é chamada (os índices de matrizes numéricos são configurados para serem sempre percorridos ordenados para cima com PROCINFO) e apenas um programa externo: em
awk
vez de vários.fonte
for in
pode fornecer índices de matriz numérica em ordem numérica, pelo menos para alguns valores ou em algumas implementações do awk, mas isso não é necessário, nem tradicional e, definitivamente, não universal. Isso acontece frequentemente em pequenos conjuntos como 2 ou 3 ou talvez 4; tente 10 ou 20 em todos os awk aos quais você tem acesso (sem PROCINFO ou WHINY_USERS em gawk) e aposto que US $ 50 pelo menos um caso não está classificado.@ind_str_asc
classifica como seqüências de caracteres, que só serão corretas para números se forem todos de um dígito (como é o seu exemplo); use@ind_num_asc
se (algum) valor puder ser 10 ou mais. E, embora agora seja menos problemático do que costumava ser, esse recurso está disponível apenas com o máximo de 4.0 .