Husmear con grep

Hace poco mi jefe (que no es informático) me mandó a que le buscara todos los correos que recibieron y enviaron algunos usuarios.
Inicialmente la petición me escandalizó, pero luego pensé que en definitiva el correo de la empresa es para la empresa y no para que chicho le mande a chicha un powerpoint de lo más chulo. No obstante me alegra irme de este trabajo.
En fin, lo importante es como lo resolvimos.

Inicialmente puse a una muchacha a abrir el webmin (uso postfix) y buscando en el íntringulis de los log buscar uno a uno los usuarios... trabajo infernal la verdad.

Luego pensando un poco me imaginé que usando grep podría ahorrarle este trabajo a la sufrida muchacha... pero de expresiones regulares no sé nada, ni de perl y solo un poco de python... luego de romperme la cabeza y leer de aqui y de aqui llegue a esta conclusión:

root@PC/var/log/#grep "^Mes.*[from|to]=<unusuario@.*" mail.log | grep -o ":[ ].*:[ ]" > ids && grep -f ids mail.log | grep ".*[from|to]=.*" | less

je... ahora explico:

como ven hay varios grep's, vamos uno por uno:

grep "^Mes.*[from|to]=<unusuario@.*" mail.log

Esto al español se traduce: Muestra(grep) todas la lineas que comiencen por Mes(^Mes) y cualquier cosa (.*) hasta que encuentre un from o un to ([from|to]) seguido por =<unusuario@ y el resto da igual (.*), todo esto lo sacamos del mail.log.

El objetivo de esto es extrer todos las lineas en las que aparezca el usuario unusuario para entonces, con esto hacer lo siguiente(para enlazar el resultado del grep anterior con el siguiente usamos |):

grep -o ":[ ].*:[ ]" > ids

aqui buscamos el patron :[ ].*:[ ] y sacamos solo lo que coincide con él, es decir, si en el grep anterior obtenemos todas las lineas que se acomodan al patron aqui sacamos la parte de las lineas que se ajustan al nuevo patron, que en este caso coincide con la manera en que postfix pone los id de los correos, para esto es la opción -o. es patrón es de la siguiente manera: primero dos puntos (:) luego un espacio ([ ]) luego lo que sea (.*), luego dos puntos más (:) y finalmente otro espacio. El resultado de esto lo colocamos en un fichero llamado ids (> ids).

Si esta operación tiene exito pasamos al proximo grep mediante (&&).

grep -f ids mail.log

Lo que sigue es más sencillo, ahora usamos el fichero ids para buscar en todo el mail.log las lineas que contengan los id de los correos, que serán los que necesitamos, para ello le indicamos a grep que el parametro que le pasamos (ids) es un fichero, y no un literal, para ello se utiliza el -f.

La salida de este ultimo grep la volvemos a filtrar de una manera similar al primero y el (| less) es para poder ver el resultado en pantalla, podríamos sustituirlo por >correos_de_unusuario_mes_Mes.txt y tendríamos ya esa información guardada para lo que haya que hacer con ella.

Repito que no me hace ninguna gracia este trabajo, me parece una barbaridad, solo publico esto porque me resultó interesante resolverlo, aunque quizás a alguien se le ocurra una idea mejor.

2 comentarios:

Alexey dijo...

Viste la búsqueda interactiva usando regexps en emacs? Es impresionantemente útil para construir un regexp.

Anónimo dijo...

La verdad que emacs solo le eché un vistazo como candidato a editor para haskell, me di cuenta que puede ser poderoso, pero que hay que dedicarle un rato. Como sea, la cosa es que emacs es una asignatura pendiente, me gustó bastante, pero ando un poco corto de tiempo con mis dos trabajos, quizas en poco tiempo logre deshacerme de uno de los dos y podré regresar a medio-full time a haskell y por extensión a emacs