5

I have a simple script that deals with hours and minutes.

If I want to calculate number of minutes since midnight having a string s hh:mm I tried splitting string then doing hh * 60 + mm

My problem is, while

$ (( tot = 12 * 60 + 30 ))
$ echo $tot
750

instead

$ (( tot = 09 * 60 + 30 ))
bash: ((: tot = 09: value too great for base (error token is "09")

As far as I understand string 09 is not to be intended as a base 10 number.

Is there a better way than simply removing leading zeros in string?

Gilles 'SO- stop being evil'
864k204 gold badges1.8k silver badges2.3k bronze badges
asked Aug 24, 2011 at 8:38

2 Answers 2

15
h=09; m=30;(( tot = 10#$h * 60 + 10#$m )); echo $tot 

The number before the # is the radix (or base)
The number after the # must be valid for the radix
The output is always decimal
You can use a radix of 2 thru 64 (in GNU bash 4.1.5)

Note that Bash requires a leading minus sign to come before the 10#, so if your number has one, adding the 10# prefix directly won't work.

As noted by enzoyib, the old alternative of $[expression] is deprecated, so it is better to use the POSIX compliant $((expr))

$(( 2#1)) == 1
$((16#F)) == 15
$((36#Z)) == 35 

I'm not sure which 'digits' are used after Z

ilkkachu
148k16 gold badges268 silver badges440 bronze badges
answered Aug 24, 2011 at 8:46
6
  • what about a litte more information about $[10#09] ??? Commented Aug 24, 2011 at 8:53
  • I enclosed it in hh extraction: hh=$[10#${hhmm%:*}] the hell of readability! :D Thanks for the quick answer! Commented Aug 24, 2011 at 9:07
  • 3
    +1, but from bash's manual page: "The old format $[expression] is deprecated and will be removed in upcoming versions of bash.". Better to use $((expr)) that is POSIX compliant. Commented Aug 24, 2011 at 11:01
  • 1
    The ksh and bash manpages describe the digits for bases higher than 36: 0-9, a-z, A-Z, @, _ (bases 36 and lower are case insensitive). Commented Aug 25, 2011 at 6:35
  • $[ expr ] is still supported in Bash 5.1 right now. It's not likely to actually go away. (It's not the only undocumented obsolete thing that Bash still secretly supports.) Commented May 19, 2022 at 12:32
5

A leading zero on a numeric constant in shell arithmetic expressions denotes an octal constant.

Here's a portable way of deleting initial zeros:

h=${h#${h%%[!0]*}}; [ -n "$h" ] || h=0

In bash, ksh or zsh, you can explicitly specify base 10 with $((10#$h)).

answered Aug 24, 2011 at 21:49

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.