6

I'm trying to pad zero to a number

a=010
printf "%04d" $a
0008

I need the "output" as "0010" it's converting the value.

and even tried with typeset

a=010
typeset -RZ2 a
echo $a

when I use the same in my script I got the following error:

Invalid -R option
  • the problem in with the input, not the output. – ctrl-alt-delor Aug 26 '13 at 12:47
14

Don't put a "0" at the beginning of the number -- it treats the number in the octal base. Simply assign the decimal number.

a=10    
printf "%04d" $a    
0010    

If you are reading the numbers from somewhere else, you may consider removing the 0s at the beginning as follows:

a=0010    
b=$(echo $a | sed 's/^0*//')    
printf "%04d" $a    
0008
printf "%04d" $b    
0010    
  • b=$(echo $a | sed 's/^0*//') – user43067 Aug 26 '13 at 8:36
  • echo simply prints the value of the variable a, which is then redirected to sed (using the | character). Now, sed receives the string (i.e., value of a), and removes all the 0s at the beginning. The character ^ indicates beginning of a line; 0* means any number of zeroes including none. This essentially returns you the number with all 0s, if any, at the beginning removed. This value is then assigned to a new variable called b. – Barun Aug 26 '13 at 9:17
  • Please, whipe useless pipe! Write b=$(sed s/^0*// <<<"$a") – F. Hauri Mar 14 '17 at 6:52
10

Under POSIX

You can drop the left 0 character with the following:

a=00010
while [ "$a" != "${a#0}" ] ;do a=${a#0};done
printf "%08d" $a
00000010

As this doesn't fork a new command session, this could be quicker than using sed.

Under

You can force decimal interpretation with the following syntax:

a=000010
printf "%08d" $((10#$a))
00000010

This could be useful for conversions:

a="0a"
printf "%04d" $((16#$a))
0010

a="00001010"
printf "%04d" $((2#$a))
0010

a="00012"
printf "%04d" $((8#$a))
0010

a="0020"
printf "%04d" $((5#$a))
0010

a="0013"
printf "%04d" $((7#$a))
0010

and so on...

a="zz"
printf "%04d" $((36#$a))
1295
  • b=$(echo $a | sed 's/^0*//') what exactly this step does ?? – user43067 Aug 26 '13 at 8:37
  • @user43067 $() generate a new command session (fork), echo $a will run in this new session, than | sed will generate a new command session to pipe to /bin/sed outer binary. – F. Hauri Aug 26 '13 at 14:40
5

You can accomplish that by using a different conversion specifier, for example the "f" specifier. From the printf manual:

f, F

The double argument is rounded and converted to decimal notation in the style [-]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. If a decimal point appears, at least one digit appears before it.

But we don't really want a floating point representation of your number, so we must specify a precision of zero. This should do it:

a=010
printf "%04.0f" $a

I'm assuming you are using Linux, but this should also work with other flavours of Unix.

  • Or, from man printf, u could use: printf "%04g" 010! +1, interesting way to explore too... – F. Hauri Aug 26 '13 at 14:51
4

typeset -Z4 a will work with zsh or ksh.

When interpreted as a number, In POSIX sh and printf, if there's a leading zero, it's interpreted as an octal number. So, you need to strip those 0s first:

printf '%04d\n' "${a#"${a%%[!0]*}"}"

Or you could use awk that doesn't have that issue:

awk 'BEGIN{printf "%04d\n", ARGV[1]}' "$a"

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.