Expansiones de bash y shell: creación de listas perezosa

¡Es esa época del año otra vez! Cuando las tiendas comienzan a colocar pedazos de plástico de colores brillantes e iluminados, todos comenzamos a sentirnos un poco festivos, y por festivos me refiero a ir de compras. Específicamente, ¡compras de regalos navideños! (Los regalos para ti mismo siguen siendo regalos, técnicamente).

Para que esto no se vuelva completamente loco, deberías hacer algunas listas de regalos. Bash puede ayudar.

Expansión de corsé

Estos no son aparatos ortopédicos: ()

Tampoco lo son estos: []

Estos son aparatos ortopédicos:{}

Las llaves le dicen a Bash que haga algo con la cadena arbitraria o cadenas que encuentre entre ellos. Múltiples cadenas son separados por comas: {a,b,c}. También puede agregar un preámbulo y una posdata opcionales para adjuntar a cada resultado expandido. Principalmente, esto puede ahorrar algo de escritura, como con rutas de archivo y extensiones comunes.

Hagamos algunas listas para cada persona a la que queremos regalar cosas. Los siguientes comandos son equivalentes:

touch /home/me/gift-lists/Amy.txt /home/me/gift-lists/Bryan.txt /home/me/gift-lists/Charlie.txt
touch /home/me/gift-lists/{Amy,Bryan,Charlie}.txt
tree gift-lists /home/me/gift-lists ├── Amy.txt ├── Bryan.txt └── Charlie.txt

Maldita sea, "Bryan" deletrea su nombre con una "i". Yo puedo arreglar eso.

mv /home/me/gift-lists/{Bryan,Brian}.txt renamed '/home/me/gift-lists/Bryan.txt' -> '/home/me/gift-lists/Brian.txt'

Expansiones de parámetros de shell

La expansión de parámetros de Shell nos permite realizar todo tipo de cambios en los parámetros entre llaves, como manipular y sustituir texto.

Hay algunos rellenos de calcetines que todos nuestros dotados merecen. Hagamos de eso una variable:

STUFF=$'socks\nlump of coal\nwhite chocolate' echo "$STUFF" socks lump of coal white chocolate

Ahora agreguemos estos elementos a cada una de nuestras listas con la ayuda del teecomando para obtener echoy expansiones para jugar bien.

echo "$STUFF" | tee {Amy,Brian,Charlie}.txt cat {Amy,Brian,Charlie}.txt socks lump of coal white chocolate socks lump of coal white chocolate socks lump of coal white chocolate

Sustitución de coincidencia de patrón

Pensándolo bien, tal vez el trozo de carbón no sea un regalo tan agradable. Puede reemplazarlo con algo mejor usando una sustitución de coincidencia de patrón en la forma de ${parameter/pattern/string}:

echo "${STUFF/lump of coal/candy cane}" | tee {Amy,Brian,Charlie}.txt cat {Amy,Brian,Charlie}.txt socks candy cane white chocolate socks candy cane white chocolate socks candy cane white chocolate

Esto reemplaza la primera instancia de "trozo de carbón" con "bastón de caramelo". Para reemplazar todas las instancias (si hubiera varias), use ${parameter//pattern/string}. Esto no cambia nuestra $STUFFvariable, por lo que aún podemos reutilizar la lista original para alguien travieso más tarde.

Subcadenas

Aunque estamos mejorando las cosas, es posible que a nuestros dotados no les guste el chocolate blanco. Será mejor que agreguemos un poco de chocolate común a nuestras listas por si acaso. Como soy muy vago, solo presionaré la flecha hacia arriba y modificaré un comando Bash anterior. Afortunadamente, la última palabra de la $STUFFvariable es "chocolate", que tiene nueve caracteres, así que le diré a Bash que siga usando esa parte ${parameter:offset}. Voy a usar tee's -abandera para append a mis listas existentes:

echo "${STUFF: -9}" | tee -a {Amy,Brian,Charlie}.txt cat {Amy,Brian,Charlie}.txt socks candy cane white chocolate chocolate socks candy cane white chocolate chocolate socks candy cane white chocolate chocolate

Tú también puedes:

Hacer esto Con este
Obtener subcadena de n caracteres en adelante ${parameter:n}
Obtener subcadena para x caracteres que comienzan en n ${parameter:n:x}

¡Allí! Ahora nuestras listas base están terminadas. Tomemos un ponche de huevo.

Prueba de variables

Sabes, puede ser el ponche de huevo, pero creo que ayer comencé una lista para Amy y la guardé en una variable a la que podría haber llamado amy. Veamos si lo hice. Usaré la ${parameter:?word}expansión. Escribirá worden error estándar y saldrá si no hay ningún amyparámetro.

echo "${amy:?no such}" bash: amy: no such

Supongo que no. ¿Quizás fue Brian en su lugar?

echo "${brian:?no such}" Lederhosen

Tú también puedes:

Hacer esto Con este
Sustituir wordsi no parameterestá configurado o es nulo ${parameter:-word}
Sustituir wordsi parameterno está desarmado o nulo ${parameter:+word}
Asignar worda parametersi no parameterestá configurado o es nulo ${parameter:=word}

Cambio de caso

¡Así es! Brian dijo que quería unos pantalones de cuero, así que me hice una nota. Esto es muy importante, así que lo agregaré a la lista de Brian en mayúsculas con la ${parameter^^pattern}expansión. La patternpieza es opcional. Solo estamos escribiendo a la lista de Brian, así que usaré en >>lugar de tee -a.

echo "${brian^^}" >> Brian.txt cat Brian.txt socks candy cane white chocolate chocolate LEDERHOSEN

Tú también puedes:

Hacer esto Con este
Poner en mayúscula la primera letra ${parameter^pattern}
Minúscula la primera letra ${parameter,pattern}
Minúsculas todas las letras ${parameter,,pattern}

Expansión de matrices

Sabes qué, todo este negocio de listas de regalos es mucho trabajo. Solo voy a hacer una serie de cosas que vi en la tienda:

gifts=(sweater gameboy wagon pillows chestnuts hairbrush)

Puedo usar la expansión de subcadena en forma de ${parameter:offset:length}para simplificar esto. Agregaré los dos primeros a la lista de Amy, los dos del medio a la de Brian y los dos últimos a la de Charlie. Voy a usar printfpara ayudar con saltos de línea.

printf '%s\n' "${gifts[@]:0:2}" >> Amy.txt printf '%s\n' "${gifts[@]:2:2}" >> Brian.txt printf '%s\n' "${gifts[@]: -2}" >> Charlie.txt
cat Amy.txt socks candy cane white chocolate chocolate sweater gameboy cat Brian.txt socks candy cane white chocolate chocolate LEDERHOSEN wagon pillows cat Charlie.txt socks candy cane white chocolate chocolate chestnuts hairbrush

There! Now we’ve got a comprehensive set of super personalized gift lists. Thanks Bash! Too bad it can’t do the shopping for us, too.