Etiquetas

, , , ,

Continuando con la serie de tutoriales sobre el uso de la BASH, después del artículo sobre el uso del historial, ahora vamos a tratar cómo agilizar nuestra escritura a la hora de enumerar nombres de ficheros y directorios mediante el uso de comodines en BASH.

Uso de comodines en BASH

Los comodines más habituales en BASH a la hora de referirse a múltiples ficheros y/o directorios son:
? para referirse a un sólo carácter.
* para referirse a cero o más caracteres.
[caracteres] para referirse a un conjunto de caracteres.
[!caracteres] para referirse a un carácter que no esté en el conjunto.

Veámoslo con un ejemplo.
$ ls
abbbb.txt abbb.txt abb.txt ab.txt a.txt b.txt
$ ls a?.txt
ab.txt
$ ls a*.txt
abbbb.txt abbb.txt abb.txt ab.txt a.txt
$ ls [ab].txt
a.txt b.txt
$ ls [!b].txt
a.txt

Pero que éstos sean los más habituales no quiere decir que no existan otros. Veámoslos.

Rangos

Los rangos son una manera simplificada de indicar conjuntos de caracteres. Así podríamos indicar una letra minúscula con [a-z] o una mayúscula que sea A,B,C o D con [A-D]. Igualmente podemos indicar el complementario de un conjunto. Veámoslo con un ejemplo. Vamos a mostrar los ficheros que empiezan por a y tienen después una letra mayúscula o minúscula pero no un número.
$ ls
a1 a2 a3 a4 aa aA ab ac ad ae af ag
$ ls a[a-zA-Z]
aa aA ab ac ad ae af ag
$ ls a[!0-9]
aa aA ab ac ad ae af ag

Tilde

No sé si tachar a la tilde como comodín como he leido alguna vez. Lo que sí es seguro es que es una expansión de la ruta del home del usuario. Por defecto significará el home de nuestro usuario, pero se puede utilizar para cualquiera simplemente añadiendo su identificador tras la tilde. Así:
$ pwd
/home/xir/tmp/text/tt
$ cd ~
$ pwd
/home/xir
$ cd ~test
$ pwd
/home/test

Llaves

Las llaves nos permiten expandir una palabra por cada cadena de caracteres contenida entre ellas y separadas por comas. Es difícil de explicar cómo funciona pero muy simple de ver con un ejemplo.
$ echo ca{mino,mion,cerola}
cacerola camino camion

Es decir, coge las partes externas a las llaves y les aplica «una ley distributiva«, creando una palabra para cada una de las cadenas contenidas entre las llaves y separadas por comas. Y pensarás, ¿realmente es útil eso? Sí, no lo dudes. Entre otras cosas, hacer una copia de seguridad de un fichero (en el ejemplo a_backapear.txt) o ver las diferencias entre dos ficheros, es tan simple como:
$ ls
a_backapear.txt
$ cp a_backapear.txt{,.bak}
$ ls
a_backapear.txt a_backapear.txt.bak
$diff a_backapear.txt{,.bak}
$

Como notas finales, indicar que debe tener al menos 2 campos, ya que sino no realiza la expansión y que se pueden anidar llaves.
$ echo l{ol}a
l{lo}a
$ echo ca{s{a,erio,eron},racol}.{jpg,txt}
casa.jpg casa.txt caserio.jpg caserio.txt caseron.jpg caseron.txt caracol.jpg caracol.txt

Comodines extendidos

En primer lugar un aviso: debes tener activa la opción extglob de BASH:
$ shopt | grep extglob
extglob on

En caso de no tenerla activa, se hace de la siguiente manera:
shopt -s extglob
Una vez verificado, podemos utilizar los siguientes patrones teniendo en cuenta que se utiliza | como separador. Para los ejemplos utilizaremos los siguientes nombres de fichero:
$ ls
carta19.txt carta1.txt cartaa.txt carta.txt

?(patron) cero o una ocurrencia de patrón. Por ejemplo:
$ ls carta?([0-9]).txt
carta1.txt carta.txt

*(patron) cero o más ocurrencias de patrón. Por ejemplo:
ls carta*([0-9]).txt
carta19.txt carta1.txt carta.txt

+(patron) una o más ocurrencias de patrón. Por ejemplo:
ls carta+([0-9]).txt
carta19.txt carta1.txt

@(patron) exáctamente uno de los patrones de la lista. Por ejemplo:
$ ls carta@(|a).txt
cartaa.txt carta.txt

!(patrón) lo que sea menos uno de los patrones de la lista. Por ejemplo:
ls carta!([0-9]).txt
carta19.txt cartaa.txt carta.txt

¿Conoces más tipos de expansiones para nombres de ficheros en BASH? Compártelas en los comentarios, por favor.