Viernes de Terminal: Bash [Expansión de Llaves]

Antes que nada quisiera disculparme, ya que el viernes pasado no pude escribir el post así que hoy agregare un extra para reponer el día perdido. 🙂

Brace Expansion

En Español expansión de llaves me parece que es una función inspirada por C Shell, esta genera combinaciones entre los caracteres que se ingresen dentro de las llaves, el orden que usa es de izquierda a derecha. No tiene nada de complicado pero es una opción que nos será muy útil en nuestros recorridos por GNU/Linux.

Ejemplo:

$ echo a{1,2,3}
a1 a2 a3

Cuando se usa con comas (,) genera combinaciones entre el valor a y los valores dentro de las llaves. Si no existiera un valor fuera de las llaves solo mostraría una vez cada valor que contiene la llave.

$ echo {a,b,c}
a b c

No es nada complejo su uso, existen otros ejemplo mas comunes como crear muchos directorios en una carpeta

$ mkdir ~/Trabajos/{uno,dos,tres,cuatro,cinco}

Esto crea cinco carpetas dentro de la carpeta trabajos, es como ingresar un comando a la vez. Creando los 5 directorios.

Existen expansión por dos puntos .. esto crea una serie de números o caracteres que van de el valor inicial a el valor final, no se deben usar números con letras.

$ echo {1..5} #Correcto
1 2 3 4 5

$ echo {a..f} #Correcto
a b c d f

$ echo {a..5} #Incorrecto
{a..5}

#Creo que nunca me acostumbrare a este color azul en la letra

Podemos ahorrar tiempo al crear un ciclo for

#En lugar de escribir
$ for (( i=1; i<=5; i++ )); do echo "Mi numero $i"; done
Mi numero 1
Mi numero 2
Mi numero 3
Mi numero 4
Mi numero 5

#Ahorramos código usando brace expansion.
$ for i in {1..5}; do echo "Mi numero $i; done
Mi numero 1
Mi numero 2
Mi numero 3
Mi numero 4
Mi numero 5

#Claro que es valido usar aunque la salida es diferente.
$ echo "Mi numero "{1..5}
Mi numero 1 Mi numero 2 Mi numero 3 Mi numero 4 Mi numero 5

Bueno creo que ya quedo claro el concepto haha ahora solo comentare que es combinable y anidado ¿A que me refiero con esto?
Con combinable a que podemos juntar una o mas llaves

$ echo {a..c}{1..3}
a1 a2 a3 b1 b2 b3 c1 c2 c3

Con anidado como muchos imaginaran puedes usar llaves de expansion dentro de llaves de expansión

$ echo {a,c{1..3},d}
a c1 c2 c3 d

Y por ultimo desde Bash 4 es posible incrementar los valores.

$echo {0..20..2}
0 2 4 6 8 10 12 14 16 18 20

Esto es todo por hoy, así que gracias por leerme gente 🙂

Extra

Como crear un bin local

Cuando digo un bin local me refiero a un directorio en el que tengamos scripts propios y sea posibles ejecutarlos como un simple comando…

Logar esto es relativamente fácil, lo primero que se necesita hacer es crear un directorio donde guardaremos los scripts.

mkdir ~/.bin #En este ejemplo estará oculta

Ahora tenemos nuestra carpeta para guardar los script pero no funcionara hasta que agregamos la ruta de el nuevo .bin a $PATH
Para esto se edita el archivo bash_profile, y se agrega la linea.

export PATH=$PATH:~/.bin

Y listo eso es suficiente para crear un bin local, claro que pedirá permisos de root si es necesario para un ejemplo escribimos un script rápido.

#!/bin/bash

echo "Hola $1, ¿Como estas?"

Guardarlo con el nombre de hola
A el script se le da permiso de ejecución y solo bastara llamarlo desde la terminal

$ hola wada
#Esto mostrara el mensaje
Hola wada, ¿Como estas?

Así con este truco rápido podrás ejecutar mas rápidos tus scripts

Eso es todo por hoy gente que estén bien 🙂
P.D. Disculpen los errores si los hay los ojos ya se me cierran hahaha 😀


26 comentarios

  1.   dhunter dijo

    Llevo tiempo en el asunto del bash y no había cogido entendido los brace expansions estos, gracias.

    Sobre el truco del path, Fedora por defecto hace algo así pero en “~/.local/bin”, mira un fragmento del bash_profile que me lo traje a Jessie.

    PATH=$PATH:$HOME/.local/bin:$HOME/bin
    export PATH

    1.    Ricardo dijo

      Tengo unas inquietudes:
      1. Como le hago para que me de dos intervalos con expancion por puntos; edades{1..24,55..90} y que me expanda edades de 1 a 24 y continue con 55 hasta noventa. como le hice no dio resultado. ¿Por qué?

      2. Si quiero que el primer valor sea nulo y continue con la numeración:
      wget: http://manga.favorito /imagen http://manga.favorito/imagen1
      Lo intenté de la sigiente forma pero no me salió wget: http://manga.favorito/imagen{,1..42} Según yo, tendria que dejar el primer nombre sin número y continuar con la numeración de 1 hasta 42 pero no fue así. ¿Por qué?

    2.    Wada dijo

      Tienes razón algunas distros tienen o tenían un .bin pero es para que todos puedan entender y que vean que es posible hacerlo en cualquier distro :D, Gracias por pasar.

  2.   demo dijo

    Muy bueno muy bueno por estos aportes de conocimiento al mundo linux y su seguridad ,algún viernes ojala pudiera leer de como formatear un pendrive en una terminal y gravar una imagen iso DVD/CD de cualquier sistema libre en una terminal.

    1.    Wada dijo

      Gracias por tus palabras hermano 😀 Prometo que el próximo viernes haré ese post. Y debo uno sobre personalizar Vim hahaha pero no quería que pensaran que solo abarcaría Vim.

  3.   edoardo_or dijo

    Excelente artículo de terminal, el mejor que he leído en mucho tiempo, contando varios blogs que publican tutos de este estilo. Muchas gracias!!

    1.    Wada dijo

      Muchas gracias 😀 buscare mantenerme al nivel.

  4.   juanli dijo

    Excelente Tip el del bin Local!
    Saludos!

    1.    Wada dijo

      Excelente, genial que te sea de utilidad, muchas gracias por pasar hermano 😀

  5.   Giskard dijo

    Muy bueno! Ni idea de esto. Gracias 🙂

    1.    Wada dijo

      De nada hermano gracias a ti por tomarte el tiempo de leerlo 😀

  6.   Ricardo dijo

    Tengo unas inquietudes:
    1. Como le hago para que me de dos intervalos con expancion por puntos; edades{1..24,55..90} y que me expanda edades de 1 a 24 y continue con 55 hasta noventa. como le hice no dio resultado. ¿Por qué?

    2. Si quiero que el primer valor sea nulo y continúe con la numeración:
    wget: http://manga.favorito/imagen http://manga.favorito/imagen1

    Lo intenté de la sigiente forma pero no me salió wget: http://manga.favorito/imagen{,1..42} Según yo, tendria que dejar el primer nombre sin número y continuar con la numeración de 1 hasta 42 pero no fue así. ¿Por qué?
    * Lo siento pero el primer post lo puse como respuesta y estaba mal en unas partes

    1.    Wada dijo

      1.- Tu lógica es incorrecta tienes que anidarlo hahaha intenta con $ echo {{1..24},{55..90}}

      2.- Igual que el anterior… $ echo "URL"{,{1..42}}

      Descuida hermano estamos para ayudarnos 🙂

  7.   jvk85321 dijo

    Para reemplazar el for con echo quedaria asi

    echo “Mi numero “{1..5}$’\n’ | sed -e :a -e ‘$!N;s/\n /\n/;ta’ | sed -e :a -e ‘$!N;s/5\n/5/;ta’

    pero prefiero printf

    printf “yo yo%d\n” {1..5}

    y usa el mismo concepto de expancion de llaves

    atte
    jvk85321

    1.    jvk85321 dijo

      Como pones los cuadros terminal????

      atte
      jvk85321

  8.   jvk85321 dijo

    Probando si la etiqueta code funciona
    jeje

    Para reemplazar el for con echo quedaria asi

    echo “Mi numero “{1..5}$’\n’ | sed -e :a -e ‘$!N;s/\n /\n/;ta’ | sed -e :a -e ‘$!N;s/5\n/5/;ta’

    pero prefiero printf

    printf “Mi numero %d\n” {1..5}

    y usa el mismo concepto de expancion de llaves

    atte
    jvk85321

    1.    jvk85321 dijo

      Me quedo con algunos errores pero funciono

      Ta vivo maluco

      Perdon por molestar

      atte
      jvk85321

      1.    Wada dijo

        Hahaha te auto respondiste pero si es entre etiquetas sin espacios…

        Y sobre la sustitución del for no es necesario hacer tanto pipe hahahaha basta con:
        echo -e "Mi numero "{1..5}"\n\b"

        Para ser honesto printf es la mejor forma de imprimir texto en scripts, es mas portable pero por tradición use echo.

      2.    Wada dijo

        ¡Me tomo los espacios! hahahahaha

        a ver ahora 😀

      3.    Wada dijo

        Que se joda es “menor que”code”mayor que” “menor que”/code”mayor que” hahahaha

      4.    jvk85321 dijo

        El problema que echo -e no es estandar, por lo que no funciona en todos los sistemas.

        Ademas sale desordenado
        jvk@jvktos:~$ echo -e "Mi numero "{1..5}"\n\b"
        Mi numero 1
        Mi numero 2
        Mi numero 3
        Mi numero 4
        Mi numero 5

        jvk@jvktos:~$
        Y con este
        jvk@jvktos:~$ echo "Mi numero "{1..5}$'\n' | sed -e :a -e '$!N;s/\n /\n/;ta' | sed -e :a -e '$!N;s/5\n/5/;ta'
        Mi numero 1
        Mi numero 2
        Mi numero 3
        Mi numero 4
        Mi numero 5
        jvk@jvktos:~$

        Creo que el segundo presenta mejor el resultado, jejejeje

        atte
        jvk85321

      5.    jvk85321 dijo

        Son un fastidio estas etiquetas ejejejej, veamos si resultan ahora
        jvk@jvktos:~$ echo -e "Mi numero "{1..5}"\n\b"
        Mi numero 1
        Mi numero 2
        Mi numero 3
        Mi numero 4
        Mi numero 5
        jvk@jvktos:~$

        Y con este
        jvk@jvktos:~$ echo "Mi numero "{1..5}$'\n' | sed -e :a -e '$!N;s/\n /\n/;ta' | sed -e :a -e '$!N;s/5\n/5/;ta'
        Mi numero 1
        Mi numero 2
        Mi numero 3
        Mi numero 4
        Mi numero 5
        jvk@jvktos:~$

        Creo que el segundo presenta mejor el resultado, jejejeje
        atte
        jvk85321

      6.    jvk85321 dijo

        Igual deja los espacios entre lineas, por eso odio el html, jajajaja

  9.   Joaquin dijo

    ¡Excelente! Te aplaudo de pies jaja

    No sabía que se podían anidar las llaves, ya que nunca probé usarlas tampoco, de verdad se ahorra bastante código y además es más legible de esta manera. Gracias!

    1.    Wada dijo

      Gracias a ti por pasar hermano, me alegra que haya sido de utilidad 🙂

      1.    Joaquin dijo

        De nada, para eso estamos acá, para compartir y aportar ideas. Yo no sé programar, sólo hice un par de cositas en Bash y publiqué en dos posts unos scripts que hice. Creo que sabiendo esto se puede hacer un código más fácil de entender.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.