20 de Abril, 2006

AWK al rescate

Ya comenté que me gusta AWK, y es que va muy bien para procesar ficheros de texto. A mi me suele funcionar para convertir un fichero de entrada en código SQL.

Resulta que un cliente tiene una base de datos de productos, y cuando todo está en marcha, se da cuenta de que hay un grupo de referencias corridas (la referencia X es la siguiente, y así sucesivamente).

Como las referencias no son consecutivas, no se me ocurría una sentencia SQL fácil, así que tiré de AWK.

Lo primero es guardar los identificadores de las filas y sus referencias:

mysql> \T tabla
Logging to file 'tabla'
mysql> select id,referencia from tblAccesorio \
where referencia between "3110909" and "3135782";

Ahora tenemos en tabla los datos necesarios, arreglamos el fichero borrando a mano la cabecera y pie, dejando algo así:

| 176 | 3110909    |
| 177 | 3111013    |
| 178 | 3111022    |
...más registros...
| 218 | 3135782    |

Lo único que hay que hacer con AWK es generar una serie de updates en las que se asigna la referencia de la linea actual al identificador anterior. Para eso jugamos con BEGIN:

BEGIN {
        # separador el 'pipe'
        FS="|";

        # procesamos la primera linea para obtener su id
        getline;
        id=$2;
}

{
        # generamos el SQL :)
        print "update tblAccesorio set referencia=\"" $3 "\" where id=" id ";";
        # tomamos el id para la siguiente vuelta
        id=$2;
}

Recordemos que BEGIN se ejecuta al comenzar el programa, y que el segundo bloque se llama para cada linea.

Solo nos queda quitar espacios del fichero de entrada y dejar a AWK que nos proporcione el SQL que pasaremos directamente al gestor de bases de datos:

$ sed "s/ //g" < tabla | awk -f procesa.awk > modifica.sql

El resultado es perfecto, solo hay que añadir el último identificador. Esto es porque tiene una referencia que falta (si desplazamos todas una posición, la última no puede obtener el dato de la siguiente). Pero por lo demás, el SQL es tal que:

update tblAccesorio set referencia="3111013" where id=176;
update tblAccesorio set referencia="3111022" where id=177;
update tblAccesorio set referencia="3111289" where id=178;
-- más SQL --
update tblAccesorio set referencia="3135782" where id=217;

No descarto que se pudiera haber arreglado esto con SQL puro y duro, pero... nos hubieramos perdido esta anotación, ¿no?

Anotación por Juan J. Martínez, clasificada en: scripting, awk.

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.

Algunas anotaciones relacionadas: