Estoy intentando obtener algunas estadísticas triviales sobre algunos resultados de depuración.
Cada línea de depuración tiene la forma(class name)(delimiter 1)(object ID)(delimiter 2)(method name)(delimiter 3)(log message)
Quiero contar cuántas líneas provienen de qué métodos.
Básicamente, si cada línea se puede reducir a (class name)(delimiter)(method name)
, quiero saber cuántas apariciones de cada una de esas reducciones aparecen en el archivo de registro.
¿Qué comando puedo ejecutar en Bash para realizar el conteo?
(Estoy haciendo esto en macOS con macports reemplazando la mayoría de las herramientas predeterminadas de estilo BSD con herramientas GNU).
Puedo extraer el nombre de la clase con grep -o -E "^.*(delimiter 1)
, extraer el nombre del método con grep -o -E "(delimiter 2).*(delimiter 3)"
, o resaltar ambos con grep --color=always -E "^.*(delimiter 1)|(delimiter 2).*(delimiter 3)"
. Me quedé atascado buscando una manera de grep
generar solo las dos coincidencias que luego podrían ejecutarse | uniq -c
para realizar el conteo.
¿Hay alguna manera de imprimir grep
ambas coincidencias para cada línea en lugar de solo una coincidencia o la línea completa?
Respuesta1
En esencia, se puede hacer con
sed -r -n 's/(^.*)(delimiter 1)(.*)(delimiter 2)(.*)(delimiter 3)(.+$)/\1(delimiter)\5/p' <( command that generates debug logs ) | sort | uniq -c | sort -rn
(adaptado deaquí)
.*
puede coincidir demasiado;sed
es codicioso y quiere hacer coincidir tanto como sea posible lo antes posible, por lo que es posible que deban ser, por ejemplo, negaciones de los delimitadores (lo que puede ser complicado si tiene delimitadores inconvenientes)- Pasar de
^
a$
es importante; si su expresión no coincide, toda la líneased
incluirá la parte no coincidente en la salida. - Los paréntesis sólo son necesarios alrededor del nombre de la clase y del método; eliminar los demás significa cambiar los números al final, porque los números se refieren a subexpresiones entre paréntesis en orden. (Incluirlos a todos hace posible mostrar más de lo que sucede en la
sed
salida, por ejemplo, cambiando el final a/\1(delimiter)\5 -- \1\2\3\4\5\6\7/p
) sort
debe ejecutarse antesuniq -c
porqueuniq -c
solo cuenta las ejecuciones de líneas idénticas consecutivas, las líneas idénticas no consecutivas obtienen recuentos separadosuniq -c
no se puede reemplazarsort -u
porquesort -u
solo descarta duplicados, no los cuenta- El final
sort
no es necesario para responder la pregunta tal como se hizo. - Sí, si usas expresiones regulares para resolver un problema, ahora tienes dos problemas.