lunes, 25 de octubre de 2010

Transformando un archivo de ids en X para reemplazar en queries del tipo SELECT ... WHERE id IN (X)

Otra útil... típico que tenemos un archivo con un montón de ids y queremos meterlos dentro de alguna query del tipo "WHERE field IN (X)", donde X está formado por todos los ids. Este comando retorna X.

$ awk -v _SQ="'" 'NR>1 { retorno = retorno ", " _SQ $0 _SQ } END { print retorno }' ids 

El archivo ids contiene un id por línea.

* Este ejemplo siempre agrega un id vacio ('') al comienzo, para quitarlo basta agregar un IF. Yo lo he dejado porque me conviene en la mayoría de casos.


Cómo enviar la salida de una query a un archivo separado por "comas" (mysql)

Esta es sencilla pero útil, cómo ejecutar una query y enviar su salida a un archivo separado por comas (o cualquier otro caracter). En PostgreSQL es trivial, pero en MySQL no existe (o al menos no lo he conseguido) un parámetro que defina un FS (field separator).

$ mysql -u root db_name < query | sed 's/\t/|/g' | tee output.csv
Dentro del archivo query está la QUERY. La salida, producto de ejecutar la query, la procesamos con sed reemplazando TABS (\t) por PIPES* (|).

* En lugar de PIPES podrían ser comas, pero no recomiendo ese caracter porque es muy común.

martes, 12 de octubre de 2010

Barajita premiada (#19) - cut & paste

Estos dos comandos son súper útiles cuando deseamos generar archivos CSV a partir de otros CSV. Sobre todo cuando necesitamos pegar columnas con otras (verticalmente). Por ejemplo:

rodolfo@rcampos-laptop:~/cutAndPaste$ cat a 
id|nombre|apellido|nombreCompleto
1|Rodolfo|Campos|Rodolfo Campos
2|Juan|Pérez|Juan Pérez
rodolfo@rcampos-laptop:~/cutAndPaste$ cat b
id|cédula
1|12345678
2|87654321
rodolfo@rcampos-laptop:~/cutAndPaste$ cut -d'|' -f2 b | paste -d '|' a -
id|nombre|apellido|nombreCompleto|cédula
1|Rodolfo|Campos|Rodolfo Campos|12345678
2|Juan|Pérez|Juan Pérez|87654321

En el ejemplo mostrado arriba hacemos lo siguiente:
  1. Cortamos la segunda columna del archivo "b" (opción -f), especificando el delimitador (-d).
  2. Pegamos la salida después del contenido de "a" y la separación de ambos archivos es marcada con un "|" (opción -d). Note que la salida que viene de la tubería (del comando anterior) se especifica como entrada del comando paste utilizando un guión.


Barajita premiada (#18) - sort

Sort, tan "sencillo" pero tan "poderoso".

El comando sort permite ordenar líneas de un flujo de bytes. Este ordenamiento se puede hacer considerando caracteres ASCII, numéricos, binarios, entre otros.

Por ejemplo:
rodolfo@rcampos-laptop:~/sort$ cat a
hello
1
3
44
4
5
foo
rodolfo@rcampos-laptop:~/sort$ sort a
1
3
4
44
5
foo
hello
rodolfo@rcampos-laptop:~/sort$ sort -n a
foo
hello
1
3
4
5
44

En el ejemplo mostrado arriba, el archivo "a" fue ordenado en orden alfabético y luego numérico (opción -n). Para ambos casos, puede observar la diferencia por las posiciones de las palabras y los números 4, 5 y 44.

Pero sort también puede ordenar un archivo con líneas con campos separados por algún caracter (Ej. CSV) rápidamente y sin mayores complicaciones. Esto sobre todo me fue de gran utilidad para ordenar un archivo que pesaba 1Gb y estaba separado por "|". Obviamente debido al tamaño, no resultaba trivial abrir el mismo con Excel y pedirle que ordenara las líneas por la columna X. Mire este ejemplo:

rodolfo@rcampos-laptop:~/sort$ cat a
name|id|type
first|3|1
second|1|1
third|2|2
fourth|0|2
rodolfo@rcampos-laptop:~/sort$ sed '1d' a | sort -t '|' -nk 2
fourth|0|2
second|1|1
third|2|2
first|3|1

En el ejemplo de arriba, es removida la primera línea del archivo con sed (1d) y luego ordenado de forma numérica (-n) considerando el segundo campo (-k 2) para un flujo con campos separados por "|" (opción -t).