Como criar uma seqüência com zeros à esquerda usando a expansão de contraventamento

38

Quando uso o seguinte, obtenho um resultado como esperado:

$ echo {8..10}
8 9 10

Como posso usar essa expansão de chave de maneira fácil, para obter a seguinte saída?

$ echo {8..10}
08 09 10

Agora que isso pode ser obtido usando seq (não tentei), mas não é isso que estou procurando.

Informações úteis podem ser restritas a essa versão bash. (Se você tiver uma solução zsh , mas não bash , compartilhe também)

$ bash -version
GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu)
    
por Bernhard 04.01.2013 / 09:41

6 respostas

58

Prefixe o primeiro número com um 0 para forçar cada termo a ter a mesma largura.

$ echo {08..10}
08 09 10

Na seção da página bash man sobre Expansão de Brace:

Supplied integers may be prefixed with 0 to force each term to have the same width. When either x or y begins with a zero, the shell attempts to force all generated terms to contain the same number of digits, zero-padding where necessary.

Observe também que você pode usar seq com a opção -w para equalizar a largura preenchendo com zeros à esquerda:

$ seq -w 8 10
08
09
10

$ seq -s " " -w 8 10
08 09 10

Se você quiser mais controle, pode até especificar um formato de estilo printf:

$ seq -s " " -f %02g 8 10
08 09 10
    
por 04.01.2013 / 10:00
7

se você usar printf

printf "%.2d " {8..10} 

isso forçará dois caracteres e adicionará um 0. 0 caso você precise de 3 dígitos, você pode mudar para "% .3d".

    
por 04.01.2013 / 09:47
7

Use um intervalo que comece com um dígito constante e retire esse dígito:

echo \ {108..110} | sed 's/ 1//g'

ou sem usar um comando externo:

a=({108..110}); echo "${a[@]#1}"

Para uso em um loop:

for x in {108..110}; do
  x=${x#1}
  …
done

embora para este caso um loop while seja mais claro e funcione em qualquer shell POSIX:

x=8
while [ $x -le 10 ]; do
  n=$((100+x)); n=${n#1}
  …
  x=$((x+1))
done
    
por 06.01.2013 / 23:53
5

Eu tenho a mesma versão bash do pôster original ( GNU bash, version 3.2.51(1)-release ) e {08..12} não funciona para mim, mas o seguinte faz:

for i in 0{8..9} {10..12}; do echo $i; done
08
09
10
11
12

É um pouco mais tedioso, mas funciona na versão OP do bash (e versões posteriores, eu diria).

    
por 22.05.2014 / 15:32
1

Para referência, acho que a largura fixa automática só ocorre com a versão mais recente do bash:

$ bash -version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

$ echo test{00..05}
test0 test1 test2 test3 test4 test5
    
por 11.10.2013 / 16:27
-3
for i in $(seq -s " " -f %0${zeros}g $ini $fin); do ....;done

zeros, ini e fin são vars, então é fácil escrever apenas zeros que você digita em 'zeros' para ini to fin sem problemas;)

    
por 11.03.2015 / 17:48