jueves, 29 de enero de 2009

HAL y dict en el laboratorio

dict nos ha sido presentado. Lo hemos conocido y estamos deseosos de charlar un rato con HAL para utilizar este nuevo recurso de su lengua.

Lo primero es pedirle a HAL que nos explique qué podemos esperar de dict. Utilizaremos el camino más corto y dejamos al lector parsimonioso que visite por su cuenta la página de manual dict(1).

dict --help

La respuesta contiene la descripción breve de 21 opciones, de las cuales seleccionamos solo dos, las que vamos a usar en nuestra conversación:


dict 1.10.11/rf on Linux 2.6.26-1-amd64
Copyright 1997-2002 Rickard E. Faith (faith@dict.org)
Copyright 2002-2007 Aleksey Cheusov (vle@gmx.net)

Usage: dict [options] [word]
Query a dictd server for the definition of a word

...
-d --database <dbname> select a database to search
-D --dbs show available databases
...


dict ---como ya sabemos--- busca en un diccionario la definición de una palabra. Desde el punto de vista de las máquinas cliente y servidor implicadas en el proceso, esto es lo mismo que decir que dict, el cliente, realiza una consulta a una base de datos existente en un servidor para dict. Es decir, "diccionario" y "base de datos en un servidor para dict" son sinónimos a todos los efectos. Dos expresiones que dicen lo mismo, si bien la primera la entendemos todos y la segunda sólo los especialistas en la materia.

O sea, que las opciones de dict que acabamos de ver se pueden igualmente expresar de la siguiente forma:


-d --database <diccionario> selecciona un diccionario en el que buscar
-D --dbs muestra los diccionarios disponibles


Si la consulta no se matiza con la opción -d, dict buscará la palabra en todos los diccionarios disponibles. Normalmente, no nos interesará este comportamiento. Lo habitual será especificar no sólo la palabra que buscamos, sino también el diccionario concreto en el que queremos buscarla. Lo cual significa que la orden más frecuente que daremos a HAL tendrá la forma:

dict -d <diccionario> [palabra]

Por otra parte ---y esto es sintácticamente novedoso--- la opción misma no es autosuficiente, requiere de su propio argumento (el diccionario en el que buscar). La estructura sintáctica sería pues:

ORDEN OPCIÓN ARGUMENTO_DE_LA_OPCIÓN ARGUMENTO_DE_LA_ORDEN

Para que quede más claro, construyamos un ejemplo de la orden anterior en nuestra lengua:

Busca en el diccionario Ingles-Español la palabra 'happy'

El análisis sintáctico sería el siguiente:

  • Busca (la orden)

  • en el diccionario (la opción)

  • Inglés-Español (el argumento de la opción)

  • la palabra 'happy' (el argumento de la orden)


Conviene retener esta posibilidad sintáctica, porque también es bastante frecuente en la lengua de HAL.

Es obvio tras la anterior consideración que antes de poder realizar una consulta en un diccionario tendremos que conocer el nombre del diccionario concreto que nos interesa, que será uno entre los muchos disponibles.

Precisamente, la opción -D nos da una lista de todos esos diccionarios:

dict -D

La respuesta es bastante larga. Parece que tendremos que leer cada entrada y localizar las que nos interesan. ¡Y así cada vez que decidamos cambiar de diccionario! ¡Menudo rollo! HAL, nos estás decepcionando.

¡Alto! Ya dijimos que es un deshonor para HAL dejarnos en la estacada, empantanados en tareas tediosas y repetitivas. HAL dispone de un recurso para evitar en este momento nuestro tedio y nuestros infundados reproches. Es un recurso nuevo. Es un recurso básico y fundamental. Es una de las razones por las que hay tantos fanáticos de HAL. Son ... ---¿lo sospechan?--- las tuberías (pipes).

Hay que detenerse todo lo necesario en este punto. Cuando nos habituemos al uso de las tuberías no habrá forma de pararnos. Haremos las delicias de nuestros amigos y dejaremos boquiabiertos a los incrédulos. Si pasamos de largo sin entender este artilugio, nos podemos despedir de dar el paso a la madurez en nuestras relaciones con HAL, nuestro enamoramiento habrá sido fugaz y no habrá lugar para el amor duradero.

Para empezar, describamos con cuidado nuestra actual tarea, la que acabamos de dejar sin resolver hace un instante: dict -D nos presenta una amplia lista de todos los diccionarios a los que puede consultar dict, pero nos interesan sólo aquellos relativos a una lengua en concreto, digamos, el español. Nuestro objetivo es conocer los nombres de los diccionarios bilingües de español para poder construir el argumento de la opción -d de dict.

Antes de seguir, preguntémonos si no podemos utilizar lo ya sabido para realizar esta tarea automáticamente. Si se recuerda el artículo HAL y mis ficheros ---léase de inmediato en caso de flojedad de memoria--- y se piensa un poco, se verá que la respuesta es afirmativa.

De igual manera que allí le pedimos a HAL que redirigiese la salida de la orden echo a un fichero, podemos redirigir la salida de dict -D a otro, llamémosle diccionarios:

dict -D >diccionarios

Y ahora podemos solicitar a HAL (con la orden grep) que busque dentro del fichero diccionarios, que acabamos de crear, las líneas que contengan la palabra "spanish". Pero antes de enviar la orden a HAL vamos a ser precavidos y matizarla para que HAL busque por la palabra "spanish" sin tener en cuenta si está en mayúsculas o minúsculas, es decir, para que busque "spanish", "Spanish", "SPANISH" o cualquier variante posible. A este fin sirve la opción -i de grep. Por tanto:

grep -i 'spanish' diccionarios

Que nos da el resultado apetecido:

eng-spa English-Spanish Freedict dictionary
spa-eng Spanish-English Freedict dictionary

El único problema de esta forma de proceder es que se crea un fichero provisional nuevo, diccionarios, que luego habrá que molestarse en eliminar ---por cierto esto se hace con la orden rm diccionarios. A ojos de HAL ello significa una carga onerosa para el usuario y, como tal, un procedimiento tedioso del que debe exonerarnos.

¿Cómo lo consigue? Pongámonos en lugar de HAL y tratemos de pensar como él. Para HAL un fichero no es más que una secuencia de bytes y un fichero de texto no es más que un flujo de caracteres, una secuencia de letras ---dicho con cierta imprecisión. Ahora bien, las órdenes que le introducimos y las respuestas que nos da tienen a todos los efectos prácticos el mismo estatuto que un fichero (flujos de texto). Preguntas, respuestas, ficheros son, desde este punto de vista, exactamente lo mismo para HAL, corrientes de datos que atraviesan a toda velocidad su territorio, pertrechado con ávidos estómagos electrónicos de todas las clases dispuestos a dar buena cuenta de ellas.

Pensemos, por ejemplo, en grep, que analizó el contenido del fichero diccionarios en busca de una palabra. Un fichero como diccionarios es un mero flujo de texto con el que alimentamos a grep para que lo procese como él sabe. ¿Por qué no hacer que grep consuma un flujo procedente de otra parte? No hay nada que se lo impida. A grep le da igual cuál sea su fuente. Es más, grep, por defecto, es decir, si no se le dan argumentos, la toma del propio dispositivo donde introducimos los datos (el dispositivo de entrada). Imaginemos este dispositivo como la cañería principal por la que entran los flujos. Esta cañería está habitualmente en manos de HAL ---en realidad de otro secuaz suyo, hasta ahora no presentado, que está continuamente recibiendo el caudal. El caso es que para dejar que grep se haga por un momento con el control de la cañería principal basta con no proporcionarle argumentos. Entonces el se adueñará de ella y empezará a devolver los resultados de su procesamiento, a medida que, línea a línea, vaya consumiendo los datos del flujo. Veámoslo un momento:

grep 'hola'

Después de pulsar Enter, alimentamos a grep enviándole líneas de texto:

Si eres grep
me devolverás una respuesta
cuando veas una línea
con la palabra hola
con la palabra hola # Esto lo devuelve grep
Adios grep
Ctrl+D

(La última línea Ctrl+D no se ve en pantalla, es lo que pulsamos nosotros ---las dos teclas a la vez--- para que la cañería vuelva a pasar a las manos de HAL).

Este experimento de alimentar a grep directamente desde la cañería principal no deja de ser un pasatiempo, pero nos viene bien para corroborar empíricamente lo que habíamos dicho, que la fuente de alimentación de grep no tiene que ser necesariamente un fichero.

De ahí surge una posibilidad feliz en extremo ---y, atención, ésta es la idea fundamental---: que la fuente de alimentación de grep sea el resultado de otra orden, que su alimento sea la salida de lo que otro súbdito de HAL ha procesado previamente. Para ello lo único que necesitaremos es un dispositivo de canalización, algo que nos sirva para canalizar el producto de un procesamiento hacia el conducto de entrada de grep.

Pues bien, este dispositivo de canalización es lo que llamamos una tubería o, simplemente, tubo (del inglés, pipe) y se representa mediante el signo |. La sintaxis en este caso es tan simple que casi da vergüenza ponerla por escrito:

ORDEN-1 | ORDEN-2

(donde la salida de la ORDEN-1 es canalizada y se convierte en la entrada de la ORDEN-2).

Sobra decir que la ORDEN-2 no tiene por qué ser grep y que infinidad de órdenes pueden verse sometidas al mismo tipo de canalización. Pero como estamos con grep y los diccionarios, volvamos al ejemplo que discutíamos antes y apliquémosle la nueva técnica.

En la mesa de laboratorio tenemos dos piezas: en primer lugar, una retorta que genera la lista completa de todos los diccionarios en los que dict puede consultar:

dict -D

En segundo lugar, un grep dispuesto a filtrar cualquier secuencia de texto que lo atraviese:

grep -i 'spanish'

Ahora conectamos con un tubo las dos piezas:

dict -D | grep -i 'spanish'

La salida de la primera orden (el flujo consistente en la lista completa de diccionarios) se convierte, en virtud de la canalización, en la entrada de la segunda (del filtro que bloquea el paso de toda línea del flujo que no contiene 'spanish'). Y la solución resultante, que se derrama en el recipiente de salida (la pantalla) es la misma de antes (la lista filtrada), pero sin pasos intermedios y sin pérdidas de tiempo:


eng-spa English-Spanish Freedict dictionary
spa-eng Spanish-English Freedict dictionary


Una vez conocido el nombre del diccionario bilingüe que nos interesa, tenemos ya el ingrediente que nos faltaba para construir completamente nuestra orden:

dict -d eng-spa bye

Que, naturalmente nos devuelve el ansiado licor:

1 definition found

From English-Spanish Freedict dictionary [eng-spa]:

bye [biː]
adiós
hastaluego, hastalavista



Resumen:

  • Para buscar una palabra en un diccionario concreto se usa la orden dict con el formato dict -d [diccionario] [palabra].

  • Las opciones de ciertas órdenes pueden requerir argumentos específicos, que han de escribirse justo después de la opción. Tal el es caso, por ejemplo, de la opción -d de dict.

  • La opción -i de grep hace que el patrón de búsqueda sea insensible a la escritura en mayúscula o minúscula de las letras que lo constituyen.

  • La orden rm elimina un fichero.

  • Una tubería (pipe) es un constructo central de la lengua de HAL que permite que la salida de una orden se convierta en la entrada de otra. Gracias a las tuberías la flexibilidad de HAL puede alcanzar límites insospechados.

No hay comentarios:

Publicar un comentario