How can I do bash arithmetic with variables that are numbers with leading zeroes?

Viewed 2666

I have the following code in a bash script, where "values" is a variable of newline separated numbers, some of which have leading 0's, and I am trying to iterate through each value in values and add each value to the variable "sum".

sum=0
while read line; do
    sum=$(( sum + line ))
done <<< "$values"

this code segment gives me the error: "value too great for base (error token is "09")", which as I understand, is because the bash arithmetic expression interprets the value "line" to be an octal value because it has a leading zero.

How can I allow for bash to interpret the value of line to be its decimal value? (e.g. 09 -> 9) for the value "line" within this bash arithmetic expression?

3 Answers

You can override the "leading 0 means octal" by explicitly forcing base ten with 10#:

sum=$(( 10#$sum + 10#$line ))

Note that, while you can usually leave the $ off variable references in arithmetic contexts, in this case you need it. Also, if the variable has leading spaces (in front of the first "0"), it won't parse correctly.

To trim a single leading zero:

"${line#0}"

To trim any number of leading zeros:

"${line##+(0)}"

For example:

$ line=009900
$ echo "${line##+(0)}"
9900

You can just get rid of the leading zeros, with something like:

shopt extglob on
x="${x##+(0)}"
[[ -z "${x}" ]] && x=0

This will remove all leading zeros and then catch the case where it was all zeros (leading to an empty string), restoring it to a single zero.

The following function (and test code) will show this in action:

#!/bin/bash

stripLeadingZeros() {
    shopt -s extglob
    retVal="${1##+(0)}"
    [[ -z "${retVal}" ]] && retVal=0
    echo -n "${retVal}"
}

for testdata in 1 2 3 4 5 0 09 009 00000009 hello 00hello ; do
    result="$(stripLeadingZeros ${testdata})"
    echo "${testdata} -> ${result}"
done

The output of that is:

1 -> 1
2 -> 2
3 -> 3
4 -> 4
5 -> 5
0 -> 0
09 -> 9
009 -> 9
00000009 -> 9
hello -> hello
00hello -> hello
Related