Quando você usa a expansão de chaves?

49

Entendo o que é expansão de braçadeira , mas não sei qual a melhor forma de usá-la.

Quando você o usa?
Por favor, ensine-me alguns exemplos convenientes e notáveis, se você tiver sua própria dica.

Benjamin
fonte

Respostas:

52

A expansão de chaves é muito útil se você tiver nomes de caminhos longos. Eu o uso como uma maneira rápida de fazer backup de um arquivo :

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

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

Você também pode usá-lo em uma sequência . Certa vez, fiz isso para baixar muitas páginas da Web:

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

ou

for i in {1..100}
do
   #do something 100 times
done
dogbane
fonte
8
Isso também pode ser usado para duplicação de argumentos. Digamos que você tenha algum programa que exija um argumento '-f' para cada arquivo funcionar. em vez de fazer program -f file1 -f file2 -f file3, você pode fazerprogram "-f file"{1..3}
Patrick
Isto é uma vergonha. Acabei de descobri-lo, mas faço o backup em caminhos extra longos por anos sem conhecer o rhis. Obrigado.
smonff
2
@Patrick: Essa falha porque programrecebe três palavras: "-f file1" "-f file2" "-f file3", em vez de 6: "-f" "file1" "-f" "file2" "-f" "file3".
Musiphil 18/05/2015
@dogbane: Usar a expansão para uso em forloop é um pouco inútil, pois você pode escrever for ((i=1; i<=100; i++))e é mais eficiente.
Musiphil 18/05/2015
30

A expansão de chaves é muito útil ao criar grandes estruturas de diretório:

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

Isso lhe dará

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

Você poderia dar um passo adiante e colocar a expansão de chaves na expansão de chaves:

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

Isso fornecerá a mesma estrutura de diretórios do exemplo acima.

cristão
fonte
3
O aninhamento é bom, mas seu exemplo de aninhamento ( mkdir -p dir1/{subdir{1,2}}/{subsubdir{1,2}}) não serve para nada. Você poderia ter feito isso: mkdir -p dir1/subdir{1,2}/subsubdir{1,2}.
Iconoclast
@iconoclast, serve a um propósito se você interpretar subdir1e subdir2no sentido não literal. Substituir subdir1com cate subdir2com dog, por exemplo.
ephsmith
2
@ephsmith: se você interpretar "subdir1" como "cat" e "subdir2" para "dog", o exemplo de aninhamento falhará, pois ele usa o subdir {1,2} e não há uma string que possa ser substituída "subdir" com isso fará subdir {1,2} retornar {gato, cachorro}.
Iconoclast
21

Uso quando quero reduzir a digitação:

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

Outro exemplo:

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

Eu o uso para comparar a saída de teste real com a saída de teste desejada durante o desenvolvimento. Se o teste nº 41 falhar, é fácil ver qual a diferença entre a saída de teste (no arquivo tests.output / 041) e a saída desejada (no arquivo tests.out / 041):

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

Alguns casos frequentes para mim são:

Para renomear:

mv myText.{txt,tex}

ou

mv myText.tex{,.old}

ou

cp myText.tex{,.backup}

(Embora seja menos complicado usar o controle de versão nas duas últimas tarefas).

Para comparar (já mencionado):

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

Existem várias ótimas respostas aqui, mas nenhuma delas menciona quando não usar expansão de chaves. Como os outros respondentes, uso bastante a expansão entre chaves na linha de comando. Também o uso em meus aliases e funções, pois posso esperar um shell inteligente.

Eu não o uso nos meus scripts de shell (a menos que haja outra razão pela qual os scripts sejam bash ou zsh, embora nesses casos seja melhor atualizar para uma linguagem de script "real" como perlou python). A expansão de chaves não é portátil, pois não está no padrão de shell POSIX. Mesmo se ele funciona em seus /bin/sh- shebang scripts shell ed, não irá funcionar em sistemas com mais despojado /bin/shconchas (por exemplo dash).

No caso de uma diferença de um único dígito, você não precisa de expansão de chaves; uma classe de personagem será suficiente:

Bashism:

diff file{1,2}

Portátil:

diff file[12]
Adam Katz
fonte
3
Uma diferença é que file{1,2}sempre se expandirá para file1 file2, enquanto se file[12]expande apenas para os nomes de arquivos existentes: ou seja, se file1existe, mas file2não existe , se file[12]expande file1apenas para . A []expansão é realmente uma versão restrita da ?expansão (e elas são chamadas de "expansões de nome de caminho").
Musiphil 18/05/19
Correta, a expansão de braçadeira não é globbing do shell (também conhecida como expansão do nome do caminho). Essa é uma boa indicação que ainda não foi mencionada: a expansão de chaves é melhor em observar caminhos inesperadamente ausentes. Você também pode expandir a chave dentro da chave.
Adam Katz