6

I'm searching for a solution to a Bash 4 problem I have.

Bash 4 is able to iterate with leading zeros.

For the line:

for i in {001..005}; do echo -n $i" ";done;echo

the output is

001 002 003 004 005

but when I try this:

a="005"; for i in {001..${a}}; do echo $i;done

or something similar, the result is:

{001..005}

What am I missing?

  • http://unix.stackexchange.com/questions/7738/how-can-i-use-var-in-a-shell-brace-expansion-of-a-sequence is related, but not a duplicate: this question has the additional twist that leading zeroes are wanted. – Gilles 'SO- stop being evil' Feb 27 '14 at 03:33

3 Answers3

5

Your problem is the order in which brace expansion and variable expansion are applied. You must force the reverse order:

a=005
eval echo {001..$a}
Hauke Laging
  • 90,279
3

Brace expansion is performed before any other expansions....

You could use seq instead:

$ a="005"; for i in $(seq -f %03g 001 ${a}); do echo $i;done
001
002
003
004
005
devnull
  • 10,691
3

Brace expansion happens very early during expansion (first thing, in fact), before variable expansion. To perform brace expansion on the result of a variable expansion, you need to use eval, but that tends to be clumsy.

The easy way to iterate is to use a counter variable.

for ((i = 1; i < 5; i++)); do echo -n $i" "; done

To add the leading zeroes, you can format the number with printf:

for ((i = 1; i < 5; i++)); do printf "%03d " $i; done

An alternative trick is to count numbers that are a power of ten larger, and strip away the extraneous prefix.

delta=1000
for ((i = $((delta+1)); i < $((delta+5)); i++)); do echo -n "${i#1} "; done