miércoles, 19 de enero de 2011

Instalando dos versiones de PHP-CLI en una misma máquina

El otro día tuvimos problemas instalando dos versiones del interprete de línea de comandos de PHP (PHP-CLI) en una misma máquina, específicamente, queríamos instalar en una máquina con Ubuntu 10.04 que ya tenía PHP5.2, PHP5.3.

Mi primo Daniel (http://dcestari.posterous.com/), quien es un crack como dicen por estos lares (en Venezuela diríamos un duro), dió con la solución...

Descargó el fichero con los fuentes de php.net y configuró utilizando las opciones que trae el .deb que descargas desde los repos. A continuación las opciones:

# ./configure --prefix=/usr/local/ --disable-cgi \
--program-suffix=5.3 \
--with-config-file-path=/etc/php5.3/cli \
--with-config-file-scan-dir=/etc/php5.3/cli/conf.d \
--build=$(dpkg-architecture -qDEB_HOST_GNU_TYPE) \
--host=$(dpkg-architecture -qDEB_HOST_GNU_TYPE) \
--sysconfdir=/etc \
--localstatedir=/var \
--disable-debug \
--with-regex=php \
--disable-rpath \
--disable-static \
--with-pic \
--with-layout=GNU \
--enable-calendar \
--enable-sysvsem \
--enable-sysvshm \
--enable-sysvmsg \
--enable-bcmath \
--with-bz2 \
--enable-ctype \
--with-db4 \
--without-gdbm \
--with-iconv \
--enable-exif \
--enable-ftp \
--with-gettext \
--enable-mbstring \
--with-pcre-regex=/usr \
--enable-shmop \
--enable-sockets \
--enable-wddx \
--with-libxml-dir=/usr \
--with-zlib \
--with-kerberos=/usr \
--with-openssl=/usr \
--enable-soap \
--enable-zip \
--with-mhash=yes \
--with-libedit \
--without-mm \
--enable-pdo \
--with-pdo-mysql \
--with-mysql --without-sybase-ct --with-sqlite \
--without-mssql --with-sqlite3 --enable-pcntl \
--without-pear

Luego, compilamos con make y lo novedoso.... en lugar de instalar el compilado con el típico make install, el descubrimiento del año (al menos para mi), utilizamos checkinstall lo que genera un .deb -con el nombre especificado- que después se puede instalar y desinstalar fácilmente con dpkg.


lunes, 10 de enero de 2011

Copiando permisos de una BD MySQL a otra

Este script lo encontré en la red y me pareció que debía publicarlo aquí por su gran utilidad:
#!/bin/bash
# adapted from (http://www.pyrosoft.co.uk/blog/2006/10/18/show-grants-for-all-users-on-mysql/)
mysql --batch --skip-column-names -e "SELECT user, host FROM user" mysql |
while read user host; do
  echo "# $user @ $host"
  mysql --batch --skip-column-names -e"SHOW GRANTS FOR '$user'@'$host'"
done

El script mostrado arriba saca todos los usuarios de la BD y luego retorna un script con los privilegios para cada uno de estos, lo que permitiría migrar privilegios y usuarios de una BD MySQL a otra.


martes, 14 de diciembre de 2010

Barajita premiada (#20) - seq con formato

Típico que necesita sacar por consola una secuencia de números, entonces utiliza el comando seq, por ejemplo:
$ seq 1 5 
1
2
3
4
5

O necesita esos números de dos en dos:
$ seq 1 2 5
1
3
5

La cosa se pone interesante cuando requiere formatos, por ejemplo obtener siempre números de dos cifras, entonces puede utilizar:
$ seq -f "%02g" 1 5
01
02
03
04
05

A este punto usted se preguntará, ¿y para qué puede serme útil esto? Pues yo no lo sé, no mentira, esto podría resultar útil para -por ejemplo- filtrar entradas de un log de apache donde cada línea lleva algo como:
192.168.0.1 - - [01/Nov/2010:00:00:33 +0100] "GET ..." 

Si quisiera extraer cada entrada para un día específico podría utilizar un script del tipo:
#!/bin/bash

for day in `seq -f "%02g" 1 31`; do
  count=`egrep -i "\[$day/Nov/[0-9:+ ]+\] \"GET $line" logs/*access.$month.log | grep " 200 " | wc -l`
  echo "$day,$line: $count"
done

¿Y para qué sirvió el seq? para hacer un "for" con valores de dos dígitos y que así tuviera sentido el grep que hacemos dentro del búcle (ver: $day).


martes, 23 de noviembre de 2010

Buscando campos únicos en archivos separados por caracteres (Ej. CSV)

El comando uniq me devuelve, para un conjunto generalmente ordenado previamente (ver: sort), un listado de líneas únicas. Inclusive me puede ayudar a contar el número de coincidencias.

¿El problema? Cuando tengo un archivo con campos separados por caracteres, como un CSV, ¿cómo hago para pedirle sólo únicos para determinados campos del archivo? Pues como Master Card, para todo lo demás AWK ;-)

$ cat a
1|1|2
1|2|3
1|1|5
2|6|7
$ awk -F '|' '!x[$1]++' a
1|1|2
2|6|7
$ awk -F '|' '!x[$1,$2]++' a
1|1|2
1|2|3
2|6|7

Fíjese que para el archivo "a" con campos separados por tuberías "|" extraigo los caracteres únicos, primero considerando el primer campo y luego considerando los primeros dos, Esto no podría hacerse fácilmente con uniq porque tendría que utilizar la vaga y precaria función -skip-chars.


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.