Expansão de Brace não é definida por POSIX, então talvez você possa abandoná-la ao todo:
seq $*
Ou:
j=$1
while [ $j -le $2 ]
do
echo $j
j=$((j+1))
done
Ou:
echo $* | awk '{for (j = $1; j <= $2; j++) print j}'
O manual do Bash diz que a expansão do contraventamento é realizada antes de qualquer outra expansão.
Estou escrevendo um script que aceita dois argumentos:
#! /bin/bash
for b in {$1..$2}; do echo $b; done
Eu corro como:
$ ./myscript 0002 0010
{0002..0010}
A saída não é o que eu espero.
Espero realizar a expansão de parâmetros antes da expansão de chaves.
A saída esperada do meu exemplo é 0002 0003 0004 0005 0006 0007 0008 0009 0010
, não 2 3 4 5 6 7 8 9 10
. Com o que você substituiria {$1..$2}
?
Espero que a solução funcione mesmo quando $1
e $2
forem sequências não apenas compostas de dígitos, mas também feitas de letras e dígitos.
Observe que os valores $1
e $2
só podem ser fornecidos como argumentos para o script. Eu acho que está claro desde o começo, mas aponte se não.
Expansão de Brace não é definida por POSIX, então talvez você possa abandoná-la ao todo:
seq $*
Ou:
j=$1
while [ $j -le $2 ]
do
echo $j
j=$((j+1))
done
Ou:
echo $* | awk '{for (j = $1; j <= $2; j++) print j}'
#! /bin/bash
seq -w $1 $2
Isso pode ser o que você encontra!
Para fazer o que você pede: realize a expansão de parâmetros antes da expansão de chaves.
Precisamos atrasar a expansão de chaves, o que é feito facilmente citando-lhe \{...\}
e chamando eval:
$ set -- 5 10
$ eval printf \'%s \' \{$1..$2\}
5 6 7 8 9 10
Isso funcionaria bem, desde que não haja comandos dentro de $1
ou $2
.
Esse é um risco de segurança dessa solução. Uma maneira de atenuar o problema é garantir que as variáveis contenham apenas números:
#!/bin/bash
a=${1//[^0-9]/} ### select only numbers from first parameter.
b=${2//[^0-9]/} ### select only numbers from second parameter.
c=$(eval printf \'%s \' \{$a..$b\})
for i in $c; do echo "$i"; done
O código acima está faltando algumas citações que esta versão corrige:
#!/bin/bash
a=${1//[^0-9]/} ### select only numbers from first parameter.
b=${2//[^0-9]/} ### select only numbers from second parameter.
c=( $(eval printf \'%s \' \{$a..$b\}) )
for i in "${c[@]}"; do echo "$i"; done
### Or just
# printf '%s\n' "${c[@]}"
Mas, para imprimir uma lista de números, um loop aritmético for
parece uma solução melhor:
#!/bin/bash
a=${1//[^0-9]/} ### select only numbers from first parameter.
b=${2//[^0-9]/} ### select only numbers from second parameter.
for (( i=$a; i<=$b; i++)); do
printf '%0*d\n' 5 "$i"
done
Use como:
$ script.sh 5 15
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
Tags bash brace-expansion