lunes, 9 de diciembre de 2013

Expresiones regulares

Resto de entradas con intenciones didácticas en la etiqueta Aprendizaje.

El de las expresiones regulares es uno de los capítulos más farragosos de los sistemas GNU/Linux pero que más atención merece, y dominarlas supone extender muy mucho las prestaciones de la consola de comandos. Vendrían a ser como una versión avanzada de los caracteres comodín y unas posibilidades exponencialmente mayores.


No tiene mayor secreto que aprenderlas y, luego, practicar para averiguar hasta qué punto podemos usarlas en búsquedas, sustituciones de texto o scripts. Las dividiremos en metacaracteres, anclas y multiplicadores.


Metacaracteres

Son conjuntos de caracteres dentro de una expresión regular y con un significado o función específicos
. : equivale a cualquier carácter.
( ) : sirve para agrupar patrones (subexpresiones o grupos).
[ ] : equivale a un carácter cualquiera de los contenidos entre corchetes.
[ - ] : equivale a un rango de caracteres.
[^ ] : excluye los caracteres que figuran entre corchetes.
{ } : introduce patrones de repetición. 
| : permite elegir entre dos expresiones.
// : delimita una expresión regular. 
\ : equivale a cualquier carácter excepto fin de línea.
\w: equivale a cualquier carácter alfanumérico y carácter _.
\W: equivale a cualquier carácter no alfanumérico.
\d: equivale a cualquier dígito.
\D: equivale a cualquier carácter no dígito.
\S: equivale a cualquier carácter menos espacio en blanco.
i: modificador para no distinguir entre mayúsculas y minúsculas.
!: excluye el carácter siguiente. 
Veamos algunos ejemplos:
[a-z]: equivale a un rango de letras minúsculas entre la a y la z.
[0-9]: equivale a un rango de dígitos entre 0 y 9.
[A-Za-z]: equivale a una letra cualquiera, ya sea mayúscula o minúscula. 
[A-Z][a-z]: equivale a una letra mayúscula seguida de una minúscula. 
[^c]: excluye el carácter c, cualquier letra que no sea la c.
[^aeiou]: excluye las vocales, es decir, equivale a cualquier consonante.
[a|b]: equivale a la letra a o a la letra b.
\w: equivale a [a-zA-Z0-9_].
\W: equivale a [^a-zA-Z0-9_].
/hola/i: representa "hola" sin distinguir mayúsculas y minúsculas.
\d: equivale a [0-9].
[!a-c]: equivale letra minúscula que no es ni a ni b ni c.
Anclas
Se refieren a la posición de la cadena.
^: comienzo de línea.
$: final de línea.
\b: principio o final de palabra.
\B: posición que no es ni al comienzo ni al final de la palabra.
<>: equivale a una palabra. 
Multiplicadores
Aluden a cuantas veces aparece en la cadena.
*: repite entre cero y más veces el carácter o subexpresión previos.
+repite entre uno y más veces el carácter o subexpresión previos.
?: repite entre cero y una vez el carácter o subexpresión previos.
{n}repite "n" veces el carácter o subexpresión previos. 
{n,m}repite entre "n" y "m" veces el carácter o subexpresión previos. 
{n,}repite al menos "n" veces el carácter o subexpresión previos. 
Sigamos con los ejemplos de anclas y multiplicadores:
^[aeiou]: una vocal al comienzo de una línea.
[aeiou]$: una vocal al final de una línea.
hola$: "hola" al final de una línea.
^$: línea vacía.
\balon: "balon" al principio o final de línea.
hola*: "hol", "hola", "holaa".
[a-z]*: una palabra en minúsculas.
^Una vez*arbol$: una línea que comienza con "una vez" y termina con "arbol".
^Una vez*[Aa]rbol$: una línea que comienza con "una vez" y termina con "Arbol" o "arbol".
hola+: "hola", "holaa", "holaaa", etc.
a{4}: "aaaa".
a{2,4}: "aa", "aaa", "aaaa".
a{2,}: "aa", "aaa", "aaaa", etc.
Lo se, un post como este valdría para ahuyentar a cualquier novato que quisiera entrar en el mundo de GNU/Linux. Quizá las expresiones regulares no sean necesarias para administrar una red doméstica o de una pequeña PYME, pero a niveles más avanzados son muy utilizadas y hacerse con ellas es fundamental. Recomiendo usar Google para encontrar construcciones más complejas y sus correspondientes explicaciones. Les dejo con un vídeo tutorial donde les explican un uso se le puede dar a las expresiones regulares.


sábado, 7 de diciembre de 2013

Filtrar datos y archivos

Resto de entradas con intenciones didácticas en la etiqueta Aprendizaje.

En ocasiones será necesario recurrir a comandos que nos ayuden a localizar archivos binarios (ejecutables), paquetes, simples ficheros de trabajo o determinados contenidos dentro de ellos. Hoy vamos a hablar de algunas órdenes que nos ayudarán en la tarea de filtrar los resultados deseados ya sea en la búsqueda de ficheros o de sus datos.

grep
Conviene aprender bien como opera este comando ya que nos resultará muy útil para encontrar cadenas de texto dentro de ficheros, lo cual conviene cuando son extensos. Es básicamente un filtro que concreta la búsqueda en función del argumento que le acompañe. Algunas de sus opciones son:
grep -i: para no distinguir entre mayúsculas y minúsculas.
grep -n: muestra el nº de línea dentro de un archivo especificado según el patrón introducido.
grep -v: muestra las líneas no coincidentes con el patrón especificado.
grep -c: en lugar de mostrarlas líneas coincidentes con el patrón introducido muestra el número de líneas que coinciden.
grep -r: busca recursivamente dentro de los subdirectorios existentes en el directorio actual.
grep -o: para que en el listado solo aparezca la parte de la línea que coincide con el patrón.
Para entender la potencia de este comando conviene que veamos algunos ejemplos:
grep opciones docu.txt: para listar todas las líneas que contengan la cadena "opciones" dentro de docu.txt.
grep "expresiones regulares" docu.txt: para listar todas las líneas que contengan la cadena "expresiones regulares" dentro de docu.txt. Cuando se trate de dos o más palabras hay que entrecomillarlas.
grep -v "compras" departamentos.txtpara excluir del listado todas las líneas que contengan la cadena "compras" dentro de departamentos.txt.
grep guitarra dredg anathema dreamtheater rush > guitarras.txt: nos envía las líneas que contengan la palabra "guitarra" de los archivos dredg, anathema, dreamtheater y rush al archivo guitarras.txt.
grep guitarra dredg anathema dreamtheater rush | tee guitarras.txt: visualiza el mismo resultado que anteriormente por pantalla y, a través de una tubería, usamos el comando tee para enviarlo al archivo guitarras.txt.
sed
Comando que permite borrar líneas y registros o sustituir cadenas de caracteres dentro de las líneas. Estas modificaciones solo se dan a efectos de visualización y los archivos originales no se ven alterados salvo que utilicemos el comando de una manera muy concreta.
sed "3d" lista.lst: elimina la línea nº 3 del archivo lista.lst.
sed "3,5d" lista.lst: elimina el rango de líneas de la 3 a la 5 del archivo lista.lst.
sed "3,$d" lista.lst: elimina el rango de líneas de la 3 en adelante del archivo lista.lst.
sed "/^$/d" lista.lst: elimina las líneas en blanco del archivo lista.lst. 
sed "s/cadena1/cadena2/g" lista.lst: sustituye cadena1 por cadena2  en el archivo lista.lst.
sed "5 s/USUARIO/usuario/g" lista.lst: sustituye USUARIO por usuario en la línea nº 5 del archivo lista.lst. 
sed -i "3,5d" lista.lst: mismo efecto que el anterior, pero esta vez los cambios se realizan en el archivo.
sort
Comando para ordenar registros y líneas de uno o más archivos.
sort listado.txt: ofrece por pantalla las líneas del archivo listado.txt  ordenadas por orden alfabético.
sort listado.txt >  listado2.txt: crea un duplicado de listado.txt con nombre listado2.txt y con sus líneas ordenadas alfabéticamente.
sort -o listado.txt listado.txt: ordena las líneas del archivo sin ofrecerlo por pantalla.
sort -r listado.txt: muestra por pantalla las líneas del archivo ordenadas en orden inverso.
sort -n listado.txt: ordena las líneas por número; útil cuando dichas líneas comienzan con un carácter numérico.
sort -u salida.txt: elimina las líneas repetidas al ordenar el archivo salida.txt
sort -m lista1.txt lista2.txt: combina ambos archivos asumiendo que los dos están previamente ordenados.
sort -b: ignora los espacios en blanco. 
tr (translate)
Permite cambiar unos caracteres por otros dentro de un archivo. Primero especificamos lo que vamos a sustituir y seguidamente lo que lo sustituye. Escribamos su sintaxis y la aclararemos después con ejemplos:

tr [opción] SET1 [SET2].

Las opciones pueden ser
-d: elimina los caracteres incidados en SET1.
-s: elimina o reemplaza los caracteres indicados en SET1. 
-c: todos los caracteres que no estén indicados en SET1 los convierte a SET2.
-t: trunca la longitud de SET1 a la de SET2.
Veamos algunos ejemplos:
echo ejemplo | tr -d emp: elimina los caracteres emp de la palabra ejemplo. Aquí ejemplo sería SET1 y emp sería SET2.
echo ejjemmpplo | tr -s [a-zA-Z]: elimina cualquier letra (representada por la expresión comodín [a-zA-Z]) duplicada de la palabra ejjemmpplo.
echo "nací el 02 de enero de 1947" | tr -c [0-9] $: sustituye todo carácter no numérico (incluidos espacios en blanco -de nuevo ver comodines-) de la expresión "nací el 02 de enero de 1947" por el carácter $.
echo murcielago | tr aeiou AEIOU: lo que aquí decimos es que de murcielago cojamos las letras aeiou y las sustituyamos por AEIOU.
Como vengo insistiendo, esto no son más que pequeños ejemplos. Documentarse y practicar es la mejor receta para aprovechar las prestaciones de estos comandos.

Y como no podría ser más a propósito, ya que hemos hablado de filtros terminemos con un vídeo de la banda de Cleveland Filter y este potente "Welcome to the fold".



lunes, 2 de diciembre de 2013

Visualizar un árbol de directorios

La de hoy va a ser una entrada breve pero interesante. Cuando tenemos un árbol de directorios muy extenso a veces queremos visualizarlo todo, con sus subdirectorios. En GNU/Linux disponemos de un comando que si bien no viene de serie (al menos en Debian 7.2) lo podemos instalar así:

sudo apt-get install tree

Exacto, el comando se llama tree (árbol). Ingenioso, ¿verdad? Pues bien, con él puedo hacer justo lo que perseguía, que no es otra cosa que mostrar en árbol todos los artistas y discos que tengo en el directorio Música de mi disco duro externo. Como sería muy extenso solo ojearemos lo poquito que tengo en la misma carpeta del disco del PC.



Como ven, añadiendo la opción -d obtenemos como resultado el árbol de directorios solo con sus subdirectorios. La órden tree monda y lironda nos daría también todos los archivos contenidos en cada directorio. Pero si nuestro árbol resultara demasiado largo como para verlo de un solo golpe de vista podemos hacer uso de la redirección para enviar la salida del comando a un archivo, de esta forma:

tree -d > musica.txt

Así podemos visualizar nuestro árbol con total comodidad con solo abrir el archivo. Y si lo que queremos es imprimir desde el terminal:

tree -d > lp

Siempre que tengamos una impresora correctamente instalada, of course.

Pues de esa lista uno de los discos que más me está gustando es el de la banda usamericana de post-rock Caspian, de los cuales les dejo este "Gone in bloom and bough".