How to add leading zeros for for-loop in shell?

BashFor Loop

Bash Problem Overview


I have a basic number for loop which increments the variable num by 1 over each iteration...

for (( num=1; num<=5; num++ ))
do
 echo $num
done

Which outputs:

1
2
3
4
5

I'm trying to make it produce the output (add leading zero before $num):

01
02
03
04
05

Without doing:

echo 0$num

Bash Solutions


Solution 1 - Bash

Use the following syntax:

$ for i in {01..05}; do echo "$i"; done
01
02
03
04
05

Disclaimer: Leading zeros only work in >=bash-4.

If you want to use printf, nothing prevents you from putting its result in a variable for further use:

$ foo=$(printf "%02d" 5)
$ echo "${foo}"
05

Solution 2 - Bash

seq -w will detect the max input width and normalize the width of the output.

for num in $(seq -w 01 05); do
    ...
done

At time of writing this didn't work on the newest versions of OSX, so you can either install macports and use its version of seq, or you can set the format explicitly:

seq -f '%02g' 1 3
    01
    02
    03

But given the ugliness of format specifications for such a simple problem, I prefer the solution Henk and Adrian gave, which just uses Bash. Apple can't screw this up since there's no generic "unix" version of Bash:

echo {01..05}

Or:

for number in {01..05}; do ...; done

Solution 3 - Bash

Use printf command to have 0 padding:

printf "%02d\n" $num

Your for loop will be like this:

for (( num=1; num<=5; num++ )); do printf "%02d\n" $num; done
01
02
03
04
05

Solution 4 - Bash

> I'm not interested in outputting it to the screen (that's what printf is mainly used for, right?) The variable $num is going to be used as a parameter for another program but let me see what I can do with this.

You can still use printf:

for num in {1..5}
do
   value=$(printf "%02d" $num)
   ... Use $value for your purposes
done

Solution 5 - Bash

From bash 4.0 onward, you can use Brace Expansion with fixed length strings. See below for the original announcement.

It will do just what you need, and does not require anything external to the shell.

$ echo {01..05}
01 02 03 04 05

for num in {01..05}
do
  echo $num
done
01
02
03
04
05

CHANGES, release bash-4.0, section 3 > This is a terse description of the new features added to bash-4.0 since > the release of bash-3.2. > > . . . > > > z. Brace expansion now allows zero-padding of expanded numeric values and will add the proper number of zeroes to make sure all values contain the same number of digits.

Solution 6 - Bash

why not printf '%02d' $num? See help printf for this internal bash command.

Solution 7 - Bash

Just a note: I have experienced different behaviours on different versions of bash:

  • version 3.1.17(1)-release-(x86_64-suse-linux) and
  • Version 4.1.17(9)-release (x86_64-unknown-cygwin))

for the former (3.1) for nn in (00..99) ; do ... works but for nn in (000..999) ; do ... does not work both will work on version 4.1 ; haven't tested printf behaviour (bash --version gave the version info)

Cheers, Jan

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBruce BlacklawsView Question on Stackoverflow
Solution 1 - BashAdrian FrühwirthView Answer on Stackoverflow
Solution 2 - BashpiojoView Answer on Stackoverflow
Solution 3 - BashanubhavaView Answer on Stackoverflow
Solution 4 - BashDavid W.View Answer on Stackoverflow
Solution 5 - BashHenk LangeveldView Answer on Stackoverflow
Solution 6 - BashBenoitView Answer on Stackoverflow
Solution 7 - Bashjd_doubleyView Answer on Stackoverflow