Por ejemplo, tengo un archivo 1.txt
que contiene:
Moscow
Astana
Tokyo
Ottawa
Quiero contar el número de todos los caracteres como:
a - 4,
b - 0,
c - 1,
...
z - 0
command-line
bash
text-processing
Set-xx
fuente
fuente
Respuestas:
Podrías usar esto:
La
sed
parte coloca una nueva línea después de cada personaje. Luego salimossort
alfabéticamente. Y por finuniq
cuenta el número de ocurrencias. La-i
bandera deuniq
se puede omitir si no desea insensibilidad a mayúsculas y minúsculas.fuente
sort -k 2
para enumerarlos alfanuméricamente.sed -e $'s/\(.\)/\\1\\\n/g'
(ver también stackoverflow.com/a/18410122/179014 )| sort -rnk 1
. Y si se trata de archivos muy grandes, como yo, solo puede probar algunos miles de líneas para obtener un proxy para los recuentos reales:cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
Un poco tarde, pero para completar el conjunto, otro enfoque de python (3), resultado ordenado:
Explicación
Lea el archivo, saltee espacios y regrese como "caracteres":
Cree un conjunto (ordenado) de exclusivos:
Cuente e imprima la aparición de cada uno de los personajes:
Cómo utilizar
chars_count.py
Ejecútelo con el archivo como argumento por:
si el script es ejecutable o:
si no lo es
fuente
Por defecto en awk el F ield S eparator (FS) es el espacio o pestaña . Como deseamos contar cada carácter, tendremos que redefinir el FS a cero (
FS=""
) para dividir cada carácter en una línea separada y guardarlo en una matriz y, al final dentro delEND{..}
bloque, imprimir sus ocurrencias totales con el siguiente comando awk :En
{for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...
bloque simplemente dividimos los personajes. Yen el
END{for (c in a) print c,a[c]}
bloque estamos haciendo un bucle para agrupara
e imprimir el carácter guardado en élprint c
y su número de ocurrenciasa[c]
fuente
Haga un
for
bucle para todos los caracteres que desea contar ygrep -io
úselos para obtener todas las ocurrencias del personaje e ignorar mayúsculas y minúsculas, ywc -l
para contar instancias e imprimir el resultado.Me gusta esto:
El script genera esto:
EDITAR después del comentario
Para crear un bucle para todos los caracteres imprimibles, puede hacer esto:
Esto contará todos los caracteres ANSI de 32 a 126; estos son los más legibles. Tenga en cuenta que esto no utiliza ignorar mayúsculas y minúsculas.
La salida de esto será:
fuente
i
del grep. (en su pregunta tenía solo 3 en el resultado esperado)grep
toda la entrada repetidamente.Aquí otra solución (en awk) ...
fuente
cat file | awk '...'
: puedes decirlo directamenteawk '...' file
.El siguiente
perl
oneliner hará el recuento. Puse la expresión regular en el contexto de la lista (para obtener el número de coincidencias) y lo puse en el contexto escalar:fuente
perl -Mfeature=say -e '$a=join("",<>);say join(",\n", map { sprintf("%s - %d", $_, ($d=()=$a=~/$_/gi)); } ("a".."z"))'
Aquí hay una solución usando Python:
Aquí hemos usado la clase
collections
del móduloCounter
para contar el número de ocurrencias de cada carácter, luego, para imprimir, hemos usado elstring
módulo para obtener todas las letras minúsculas por la variablestring.lowercase
.Guarde el script anterior en un archivo con el nombre que desee, por ejemplo
count.py
. Ahora desde el mismo directorio donde está guardadopython count.py
el archivo, simplemente puede ejecutarlo para ejecutar el archivo, desde cualquier otro directorio use la ruta absoluta al archivo para ejecutarlo, es decirpython /absolute/path/to/count.py
.fuente
Hace un tiempo escribí un programa en C para hacer eso, porque lo necesitaba para mirar archivos grandes y producir algunas estadísticas.
compilar con (suponiendo que el código fuente reside en
character-distribution.c
):corre con:
Si no tiene un compilador de C listo, instale GCC:
fuente
Solución similar a @heemayl, con código más estricto, que funciona en Python 2.7 y Python 3.
La primera declaración
count = collections.Counter(…)
hace todo el trabajo real.fileinput.input()
lee cada línea de la entrada, que puede canalizarse a través de stdin o como argumentos de línea de comandos.*
hace que considere un carácter a la vez en lugar de una línea a la vez.count = Counter(…)
cuenta las ocurrencias de cada personaje de manera eficiente, en una sola pasada, y almacena el resultado en lacount
variable.La segunda línea solo imprime los resultados.
'{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase
hace una lista de cada personaje y su cuenta.print(',\n'.join(…))
lo pone en el formato deseado: uno por línea, separado por comas, pero sin coma en la última línea.fuente
GNU awk 4.1
Si tiene una versión anterior de GNU awk, puede usarla
for (c in b) print c, b[c]
.fuente
Aquí está la respuesta usando ruby. Se realiza cambiando la cadena en una lista uniq de los diferentes caracteres y utilizando el método de conteo en cada uno de ellos.
fuente