Como funciona a expansão de chaves no shell?

0

O comando echo {1..3}-{1,2} imprime 1-1 1-2 2-1 2-2 3-1 3-2 . Eu entendo a maneira como essas chaves podem ser usadas. Mas o que realmente são eles?

É o trabalho de sh / bash para analisá-los / expandi-los e entregar a versão expandida para o programa executado?

Em caso afirmativo, que outros truques podem fazer e existe uma especificação?

Além disso, há um nome para isso?

O ls *.txt é tratado internamente de maneira semelhante?

Existe uma maneira de conseguir uma repetição de n-times de um argumento? Tipo (não funcionando, claro, apenas um conceito): cat test.pdf{*3}cat test.pdf test.pdf test.pdf ?

    
por Matmarbon 06.12.2017 / 01:42

2 respostas

4

Eles são chamados de expansão de chave .

Essa é uma das várias expansões feitas por bash , zsh e ksh , a expansão% filename*.txt sendo outra delas. A expansão de chave não é coberta pelo padrão POSIX e, portanto, não é portátil. Você pode ler sobre isso em manual do bash .

Sugestão de @ @ Arrow: para obter apenas cat test.pdf test.pdf test.pdf com a expansão de chaves, você teria que usar esse "hack":

#cat test.pdf test.pdf
cat test.pdf{,}

#cat test.pdf test.pdf test.pdf
cat test.pdf{,,}

#cat test.pdf test.pdf test.pdf test.pdf
cat test.pdf{,,,}

Alguns usos comuns:

for index in {1..10}; do
   echo "$index"
done

touch test_file_{a..e}.txt

Ou outro "hack" para imprimir uma string 10 vezes:

printf -- "mystring\n%0.s" {1..10}

Esteja ciente de que a expansão de chaves em bash é feita antes de expansão do parâmetro, portanto, um erro comum é:

num=10
for index in {1..$num}; do
   echo "$index"
done

(o ksh93 shell lida com isso)

    
por 06.12.2017 / 02:22
1

A resposta da PesaThe responde a aspectos importantes da questão. Há várias coisas que quero adicionar.

O asterisco em ls *.txt é manipulado pelo shell e, portanto, é controlado pelas opções de shell que podem ser alteradas pelos shell built-ins. Nesse caso, pode-se desabilitar a expansão do asterisco executando set -f e habilitar novamente por set +f .

Outra coisa é que qualquer um que queira tornar o script portátil deve verificar o padrão POSIX. Por exemplo, {1..9..2} expande para 1 3 5 7 9 em bash 4, mas não expande em bash versões inferiores ou em sh .

Espero que isso ajude.

    
por 06.12.2017 / 07:31