Gravatar de Armonth

Cosas que se aprenden: Cat y grep

El interprete de comandos de un Unix — a.k.a consola — o habitualmente BASH (que sí: hay otras terminales aparte de bash pero es casi un estándar actualmente) siempre se le ha atribuido un potencial enorme y no es ninguna mentira, encadenando comandos (programas) se pueden llegar a hacer scripts bastante complejos que a menudo incluso nos sirven de sustitutos de programas más tradicionales (programar y compilar).

Sin llegar a niveles altos (el shell scripting y todo lo que huela a programación me supera por falta de tiempo) uno se da cuenta que jamás le sacara todo el jugo y potencial.

Un ejemplo lo tenemos en dos programas de lo más sencillo: cat y grep.

El primero saca por pantalla un fichero y el segundo se puede usar para mostrar líneas que coincidan con un patrón (o al revés: las que no coincidan).

Hasta ahí nada particular, hace tiempo me metieron la primera en la frente con un comentario que decía algo así:

Acabas de ganar el Cat Useless Award por este uso del cat.

¿Qué hice? pues la siguiente orden:

 cat fichero | grep patrón

Con el noble objetivo de mostrar por pantalla todas las líneas que encajaran con patrón dentro de fichero. Debería haber usado:

 grep patrón fichero

¿La diferencia? Un cat y un pipe menos por un lado, por el otro es más óptimo y rápido:

 $ time cat fichero | grep patrón

 real    0m0.049s
 user    0m0.048s
 sys     0m0.030s

 $ time grep patrón fichero

 real    0m0.027s
 user    0m0.024s
 sys     0m0.010s

A mayor es el fichero, más se nota la diferencia, cuando hablamos de un grep no tiene mayor importancia pero cuando son shellscripts complejos la cosa puede cambiar.

Esto fue hace tiempo, ahora viene la “versión 2.0″: Usar grep y wc -l para saber cuántas líneas coinciden con un patrón es otra manera de desperdiciar tiempo de proceso.

 $ time grep patrón fichero | wc -l
 6320

 real    0m0.196s
 user    0m0.018s
 sys     0m0.063s

En su lugar, mejor usar grep con el parámetro -c:

 $ time grep -c patrón fichero
 6320

 real    0m0.026s
 user    0m0.009s
 sys     0m0.015s

Este caso ya sangra más: 8 veces más rápido el segundo ejemplo que el primero, o en patrones pequeños (5-20 resultados) 2.5 veces más rápido.

Con estos simples ejemplos me doy cuenta que la manera más simple no siempre es la más óptima.

El día que me meta finalmente en la programación (nada de editar cosas: hacerlas desde cero) creo que voy a convertirme en un devorador de artículos sobre optimización.

Comentarios cerrados