Parsear ficheros en Bash

Estos días me veo obligado a estar viviendo en la terminal entre ficheros de log con objeto de detectar fallos y posibles mejoras de un importante procedimiento administrativo en el que andamos inmersos.

Entre las distintas operaciones que realizo sobre los ficheros se encuentra la necesidad de extraer cierta información de los logs para poder compararla con datos de otros ficheros o incluso de las bases de datos.

Considerando que podría ser de interés para algunos de vosotros he optado por compartir algunas formas de extraer información de un fichero de texto.

Datos de ejemplo

Supongamos que tenemos un fichero CSV con un contenido como el siguiente

null

que ha sido obtenido lanzando el siguiente comando en la terminal

for i in {1..15}; do  echo $i";Alumno $i;"$[ ( $RANDOM % 20 )  + 1 ] >> /tmp/lista.lst; done

nuestro objetivo será sacar el contenido de la primera columna que contiene una serie de números que sirven de identificador único de las distintas entradas.

El comando cut

Quizás sea el más sencillo de los dos métodos que vamos a ver.

cat /tmp/lista.lst | cut -d\; -f1

donde:

  1. -d permite indicar el Delimitador o carácter que separa los distintos valores que aparecen en cada fila. Como los datos son un fichero CSV separados por ; y éste tiene sentido en las líneas de comandos Bash (es el separador de diferentes comandos en una pipe) le ponemos por delante la barra invertida (\) para que no lo interprete. Si el separador fuese : bastaría con utilizar en el comando cut un -d:.
  2. -f1 indica la posición de la columna que nos interesa (es 1-index por lo que le estamos pidiendo el primer valor que es el que corresponde con el ID que queremos recuperar)

El comando awk

Aunque pueda resultar algo más engorroso extraer información con awk, presenta como principal ventaja el poder generar resultados más elaborados una vez que le pillas el truco a su sintaxis.

Limitándonos al ejemplo propuesto (obtener los valores de la columna de identificadores) deberíamos lanzar un

cat /tmp/lista.lst | awk -F\; '{ print $1 }'

donde

  1. -F tiene la misma finalidad que el -d del comando cut (la barra invertida es por el mismo motivo)
  2. $1 es equivalente al -f1 de cut.

Conclusión

Dos formas distintas de obtener el mismo resultado (extraer información de un fichero de texto en el que los datos están separador por determinado carácter).

El comando awk, aunque algo más engorroso de escribir nos permite resultados más complejos; sirva como pequeño ejemplo para despertar vuestro interés el siguiente fragmento de código

cat /tmp/lista.lst | awk -F\; '{ print "El ID es " $1 }'

Aunque existen editores de texto (y complementos de GEdit) que permiten la selección de datos por columnas (¿alguien me recomienda uno realmente bueno?)

  • No siempre los delimitadores coinciden en las mismas posiciones por lo que resulta imposible hacerlo con el editor de textos
  • Hacerlo gráficamente es viable cuando lo vamos a hacer una sola vez… si el proceso tenemos que repetirlo múltiples veces se vuelve una auténtica tortura ;)

Espero que el artículo os sea de utilidad.

11 Respuestas a “Parsear ficheros en Bash”


  1. 1 Julio 1 diciembre 2010 a las 11:57 am

    Quizás lo más interesante es poder empezar con la programación de tareas en bash para luego ir complicando el script para realizar tareas más complejas, por ejemplo integrando con correos electrónicos y con acceso a bases de datos o incluso o con otros programas que estén en otros lenguajes (veáse php u otros).

    Un saludo.

    • 2 Informático de Guardia 1 diciembre 2010 a las 12:05 pm

      ¿Es una petición formal de algunos artículos sobre la programación en Bash?

      Curiosamente no suelen tener demasiada aceptación los artículos que sobre el tema he publicado en el blog pero, si os interesan, no tenéis más que pedirlo en los comentarios.

      Salu2 y gracias por la sugerencia @Julio

      • 3 Julio 3 diciembre 2010 a las 10:46 am

        Se me ocurren muchas ideas para poder tratar información con estas técnicas, que seguro para muchos son demasiado aburridas.

        Un ejemplo sería como “consolidar información” que trabajan los profesores a un “repositorio común”, y como procesar distintas alertas y distribuir dicha información procesada a los interesados.

        Ejemplo, cada profesor trabaja unos aspectos en sus clases y los evalúa.

        Para él debe ser fácil ir anotando esta información.

        Cada profesor debe poder saber de manera sencilla, distintas informaciones que saldrán de tratar estadísticamente estos datos.

        Pero el profesor no está solo, no hay un sólo profesor para el alumno. De hecho cada evaluación debe ser compartida con los demás profesores, pues luego hay que dar los resultados a los alumnos, etc, etc. No me quiero enrollar.

        Aquí ya se ven varios aspectos para poder trabajar y seguro que hay tareas en la que bash y la generación de distintos “scripts” puede hacer más fácil y menos tediosa la labor docente.

        Un saludo.

        • 4 Informático de Guardia 3 diciembre 2010 a las 11:04 am

          Veo que te ha gustado el tema @Julio (me alegro)

          De todos modos para lo que sugieres me metería mejor en el desarrollo de alguna mini aplicación web (php si no te quieres meter en Java) o bien evaluaría alguna de las aplicaciones opensource que existen para la gestión de alumnos ;)

          Un abrazo Julio y, aunque creas que pueda resultar aburrido, estaría encantado de tratar contigo el tema de la gestión docente

  2. 5 hatteras 6 diciembre 2010 a las 9:31 am

    ¿ De donde te has sacado el verbo “parsear” ?
    Si me pongo en la piel de un usuario de windows o de un recién llegado a linux y veo ese “verbo” me asustaria pensando en lo dificil que debe ser un sistema operativo que usa semejante “palabro”.
    En cambio el tema es interesante.

  3. 7 savarito 11 diciembre 2010 a las 10:48 am

    >> Aunque existen editores de texto (y complementos de GEdit) que permiten la selección de datos por columnas (¿alguien me recomienda uno realmente bueno?)

    Puedes usar VIM que admite expresiones regulares. Por ejemplo, para seleccionar la primera columna:

    :/^.\{-};

    Pero también existen plugins para trabajar con archivos CSV en VIM. Por ejemplo:

    http://vim.wikia.com/wiki/Working_with_CSV_files

    Con esto, puedes navegar por las columnas usando HJKL, buscar y sustituir en una columna, borrar columnas e incluso ordenar el texto por columnas.

    A todo esto, ¿no crees que es mejor usar Excel o cualquier hoja de cálculo que permita trabajar con archivos CSV?

    • 8 Informático de Guardia 11 diciembre 2010 a las 10:57 am

      Sólo soy un iniciado en Vi/Vim por lo que no suelo usarlo como editor por defecto (no me siento lo suficientemente “hombre” para hacerlo ;) )

      Respecto a Excel (en su defecto OpenOffice Calc) estaríamos en el mismo problema: tener que hacerlo manualmente con la interacción del usuario lo cual quiero evitar pues lo que busco es poder automatizar el proceso mediante algún script ;)

      Gracias @Savarito por tu participación y sugerencia (echaba de menos que alguien recogiese el pañuelo “lanzado” en el artículo)

  4. 9 Jorge 15 marzo 2011 a las 6:12 pm

    muchas gracias aunque mi problema es un tris mas complejo me sirve de inicio muchas gracias


  1. 1 BlogESfera.com Trackback en 29 noviembre 2010 a las 1:16 pm

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s




Patrocinadores

informática y electrónica megastore online de electrónica y accesorios turismo en cuenca blog de coches y motor Anunciate aquí gana dinero con encuestas Alojamiento web de confianza Las últimas noticias de ciencia, tecnología, espacio y la actualidad internacional

¿Hablamos?

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevos mensajes por correo.

Únete a otros 1.280 seguidores

Participa

Histórico


Twitter

  • RT @malcer_quaid: "Nunca he conocido a nadie tan ignorante del que no pudiera aprender algo." - Buda 10 hours ago
  • RT @ildecortes: Eh! Han tirado 2 bengalas! 90 mil euros y 15 días, no? 1 day ago
  • @migmae Pues me voy a tener que buscar uno... gracias por avisar de su existencia :) 1 day ago
  • RT @Desalentado1: Cómo puede ser que para mantener la sanidad y educación,todo sean problemas y para Bankia habrá todo el capital necesa ... 1 day ago
  • RT @vcuevas: Rescatar Bankia, 19000 millones de €; mantener la sanidad y Educación, 10.000 m de €; que el Gobierno nos llame idiotas, n ... 2 days ago

Seguir

Get every new post delivered to your Inbox.

Únete a otros 1.280 seguidores