46

When I use the following, I get a result as expected:

$ echo {8..10}
8 9 10

How can I use this brace expansion in an easy way, to get the following output?

$ echo {8..10}
08 09 10

I now that this may be obtained using seq (didn't try), but that is not what I am looking for.

Useful info may be that I am restricted to this bash version. (If you have a zsh solution, but no bash solution, please share as well)

$ bash -version
GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu)
71

Prefix the first number with a 0 to force each term to have the same width.

$ echo {08..10}
08 09 10

From the bash man page section on Brace Expansion:

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.

Also note that you can use seq with the -w option to equalize width by padding with leading zeroes:

$ seq -w 8 10
08
09
10

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

If you want more control, you can even specify a printf style format:

$ seq -s " " -f %02g 8 10
08 09 10
  • 8
    After just found out about the echo {08..10} solution, however, it is only introduced for bash version 4 and up. – Bernhard Jan 4 '13 at 9:05
  • That makes me a little uncomfortable that bash does that. For a bunch of utilities (for example perl) a leading zero indicates an octal number. I suppose it is not often you want a sequence of octal numbers... – kurtm Oct 11 '13 at 15:01
  • 5
    It should be noted that you can also prefix the numbers when giving then to seq with the -w switch like so: seq -w 003 produces the numbers 001, 002, and 003. – slm May 6 '14 at 19:08
  • @kurtm don't worry about leading zeroes. That could hurt when something tries to parse a number. What this is really useful at is to generate a file name sequence foo_00001.someextension where nearly all sorting contexts provide a sane ordering. – Stéphane Gourichon Jan 16 '17 at 15:11
9

if you use printf

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

this will force to be 2 chars and will add a leading 0. In case you need 3 digits you can change to "%.3d ".

  • Thanks for your answer. I am aware of the printf solution, but it is not really making this easier. I am hoping that there is some hidden trick that does the job :) – Bernhard Jan 4 '13 at 8:49
  • This is the only answer that seems versatile enough to handle any circumstance for origin of the number to pad. I'm using a counter as I loop through files. This printf solution zero pads flawlessly while all others seem to focus on generating zero-padded numbers rather than zero-padding existing numbers. – mightypile Jan 2 '15 at 2:11
7

Use a range that starts with a constant digit and strip that digit off:

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

or without using an external command:

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

For use in a for loop:

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

though for this case a while loop would be clearer and works in any POSIX shell:

x=8
while [ $x -le 10 ]; do
  n=$((100+x)); n=${n#1}
  …
  x=$((x+1))
done
  • I accepted this answer above the other answers, because it satisfies the request for Bash 3.x. Especially as I needed the for loop anyhow. – Bernhard Jan 25 '13 at 23:06
6

I have the same bash version of the original poster (GNU bash, version 3.2.51(1)-release) and {08..12} doesn't work for me, but the following does:

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

It's a little more tedious, but it does work on the OP version of bash (and later versions, I would assume).

  • I did not think about this solution (although in my case I actually also want to number 0001 1000, but your principle works of course. – Bernhard May 22 '14 at 14:01
1

For reference, I think automatic fixed-width only occurs with the latest version of 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
-3
for i in $(seq -s " " -f %0${zeros}g $ini $fin); do ....;done

zeros, ini and fin are vars, so its easy, yo write only zeros that u say in 'zeros' for ini to fin without problems ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.