Tengo 100 millones de filas en mi archivo.
Cada fila tiene solo una columna.
p.ej
aaaaa
bb
cc
ddddddd
ee
Me gustaría enumerar el recuento de caracteres
Me gusta esto
2 character words - 3
5 character words - 1
7 character words - 1
etc.
¿Hay alguna manera fácil de hacer esto en la terminal?
text-processing
Giri
fuente
fuente
Respuestas:
El primer
awk
filtro simplemente imprimirá la longitud de cada línea en el archivo llamadofile
. Supongo que este archivo contiene una palabra por línea.El
sort -n
(ordenar las líneas de la salida deawk
numéricamente en orden ascendente) yuniq -c
(contar el número de veces que cada línea ocurre consecutivamente) creará la siguiente salida a partir de eso para los datos dados:Esto es analizado por el segundo
awk
script que interpreta cada línea como "X número de líneas que tienen caracteres Y" y produce la salida deseada.La solución alternativa es hacerlo todo
awk
y mantener conteos de longitudes en una matriz. Es una compensación entre eficiencia, legibilidad / facilidad de comprensión (y por lo tanto mantenibilidad) qué solución es la "mejor".Solución alternativa:
fuente
Otra forma de hacerlo todo
awk
solowords[length()]++
use la longitud de la línea de entrada como clave para guardar el conteoEND{for(k in words)print k " character words - " words[k]}
Después de procesar todas las líneas, imprima el contenido de la matriz en el formato deseadoComparación de rendimiento, los números seleccionados son los mejores de dos carreras
Si el archivo solo tiene caracteres ASCII,
No estoy seguro de por qué el tiempo
perl
no cambió mucho, probablemente la codificación debe establecerse de otra manerafuente
length
sin()
funciona perfectamente bien aquí, por lo que podría ser redundante agregar llaves. Sin embargo, estoy usando GNU awk.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
Aquí hay un
perl
equivalente (con - opcional - ordenar):fuente
{$a<=>$b}
después de lasort
solucionaría eso. Alternativamente, uno podría usar una matriz normal con teclas numéricas y simplemente omitir cualquier tecla donde el valor sea cero / indefinido.Una alternativa una llamada a awk GNU, usando printf :
El algoritmo central solo recopila los recuentos de caracteres en una matriz. La parte final imprime los recuentos recopilados formateados con printf.
Rápido, simple, una sola llamada a awk.
Para ser precisos: se utiliza algo más de memoria para mantener la matriz.
Pero no se llama ningún tipo de ordenación (los índices de matrices numéricas se configuran para que se recorran siempre ordenados hacia arriba con PROCINFO), y solo un programa externo: en
awk
lugar de varios.fuente
for in
puede suceder que proporcione índices de matriz numérica en orden numérico al menos para algunos valores o en algunas implementaciones awk, pero eso no es obligatorio, no es tradicional y definitivamente no es universal. A menudo sucede para conjuntos pequeños como 2 o 3 o tal vez 4; pruebe 10 o 20 en cada awk al que tenga acceso (sin PROCINFO o WHINY_USERS en gawk) y apuesto a $ 50 al menos un caso no está ordenado.@ind_str_asc
se ordena como cadenas, que serán correctas para los números solo si son todos de un solo dígito (como lo es su ejemplo); use@ind_num_asc
if (any) los valores pueden ser 10 o más. Y aunque ahora es un problema menor de lo que solía ser, esta característica solo es gawk 4.0 .