¿Cuándo usas la expansión de llaves?

Respuestas:

52

La expansión de llaves es muy útil si tiene nombres de ruta largos. Lo uso como una forma rápida de hacer una copia de seguridad de un archivo :

cp /a/really/long/path/to/some/file.txt{,.bak}

copiará /a/really/long/path/to/some/file.txta/a/really/long/path/to/some/file.txt.bak

También puedes usarlo en una secuencia . Una vez lo hice para descargar muchas páginas de la web:

wget http://domain.com/book/page{1..5}.html

o

for i in {1..100}
do
   #do something 100 times
done
dogbane
fuente
8
Esto también se puede usar para la duplicación de argumentos. Digamos que tiene algún programa que requiere un argumento '-f' para que cada archivo funcione. en lugar de hacerlo program -f file1 -f file2 -f file3, puedes hacerloprogram "-f file"{1..3}
Patrick
Es una lástima. Lo acabo de descubrir pero hago la copia de seguridad en caminos extra largos durante años sin saberlo. Gracias.
smonff
2
@Patrick: que falle debido programconsigue tres palabras: "-f file1" "-f file2" "-f file3"en vez de 6: "-f" "file1" "-f" "file2" "-f" "file3".
musiphil
@dogbane: Usar la expansión para usarlo en un forbucle es un poco inútil, ya que puedes escribir for ((i=1; i<=100; i++))y es más eficiente.
musiphil
30

La expansión de llaves es muy útil al crear grandes estructuras de directorios:

mkdir -p dir1/{subdir1,subdir2}/{subsubdir1,subsubdir2}

Esto te dará

find dir1 -type d
dir1
dir1/subdir1
dir1/subdir1/subsubdir1
dir1/subdir1/subsubdir2
dir1/subdir2
dir1/subdir2/subsubdir1
dir1/subdir2/subsubdir2

Incluso podría ir un paso más allá y poner la expansión de llaves en la expansión de llaves:

mkdir -p dir1/{subdir{1,2}}/{subsubdir{1,2}}

Esto le dará la misma estructura de directorio que el ejemplo anterior.

cristiano
fuente
3
La anidación es agradable, pero su ejemplo de anidación ( mkdir -p dir1/{subdir{1,2}}/{subsubdir{1,2}}) en realidad no tiene ningún propósito. Que podría haber hecho esto simplemente: mkdir -p dir1/subdir{1,2}/subsubdir{1,2}.
iconoclasta
@iconoclast, sirve para un propósito si interpreta subdir1y subdir2no en sentido literal. Reemplazar subdir1con caty subdir2con dogpor ejemplo.
ephsmith
2
@ephsmith: si interpreta "subdir1" como "cat" y "subdir2" para "dog", entonces el ejemplo de anidación falla, ya que utiliza subdir {1,2}, y no hay cadena que pueda reemplazar "subdir" con eso hará subdir {1,2} return {cat, dog}.
iconoclasta
21

Lo uso cuando quiero reducir la escritura:

geany /path/to/file1 /path/to/file2
# versus
geany /path/to/file{1,2}

Otro ejemplo:

wajig install libpam0g-dev libiw-dev libdb-dev
# versus
wajig install lib{pam0g,iw,db}-dev
Tshepang
fuente
12

Lo uso para comparar la salida de prueba real con la salida de prueba deseada durante el desarrollo. Si la prueba # 41 falla, es fácil ver cuál es la diferencia entre el resultado de la prueba (en el archivo tests.output / 041) y el resultado deseado (en el archivo tests.out / 041):

$ diff tests.{out,output}/041
Bruce Ediger
fuente
10

Algunos casos frecuentes para mí son:

Para renombrar:

mv myText.{txt,tex}

o

mv myText.tex{,.old}

o

cp myText.tex{,.backup}

(Aunque es menos complicado usar el control de versiones para las últimas 2 tareas).

Para comparar (ya mencionado):

diff path{1,2}/a.txt
imz - Ivan Zakharyaschev
fuente
3

Aquí hay varias respuestas excelentes, pero ninguna de ellas menciona cuándo no usar la expansión de llaves. Al igual que los otros respondedores, utilizo bastante la expansión de llaves en la línea de comando. También lo uso en mis alias y funciones, ya que puedo esperar un shell inteligente.

Yo no lo uso en mis scripts de shell (a menos que haya alguna otra razón los scripts deben ser bash o zsh, aunque en esos casos, lo mejor es actualizar a un "verdadero" lenguaje de scripting como perlo python). La expansión de llaves no es portátil ya que no está en el estándar de shell POSIX. Incluso si funciona en sus /bin/sh- shebang shell scripts ed, no va a funcionar en sistemas con más despojados /bin/shconchas (por ejemplo dash).

En el caso de una diferencia de un solo dígito, no necesita expansión de llaves; bastará una clase de personaje:

Bashismo

diff file{1,2}

Portátil:

diff file[12]
Adam Katz
fuente
3
Una diferencia es que file{1,2}siempre se expandirá a file1 file2, mientras que se file[12]expande solo a los nombres de archivo existentes: es decir, si file1existe pero file2no existe , se file[12]expande file1solo. La []expansión es realmente una versión restringida de ?expansión (y se llaman "expansiones de nombre de ruta").
musiphil
Correcto, la expansión de la llave no es un bloqueo de shell (también conocido como expansión de nombre de ruta). Esa es una buena llamada que realmente no se ha mencionado todavía: la expansión de llaves es mejor al notar caminos inesperadamente ausentes. También puede englobar dentro de la expansión de la llave.
Adam Katz