[bash] Convert string into integer in bash script - "Leading Zero" number error

In a text file, test.txt, I have the next information:

sl-gs5 desconnected Wed Oct 10 08:00:01 EDT 2012 1001

I want to extract the hour of the event by the next command line:

hour=$(grep -n sl-gs5 test.txt | tail -1 | cut -d' ' -f6 | awk -F ":" '{print $1}')

and I got "08". When I try to add 1,

 14 echo $((hour+1))

I receive the next error message:

./test2.sh: line 14: 08: value too great for base (error token is "08")

If variables in Bash are untyped, why?

This question is related to bash

The answer is


In Short: In order to deal with "Leading Zero" numbers (any 0 digit that comes before the first non-zero) in bash - Use bc An arbitrary precision calculator language

Example:

a="000001"
b=$(echo $a | bc)
echo $b

Output: 1

From Bash manual:

"bc is a language that supports arbitrary precision numbers with interactive execution of statements. There are some similarities in the syntax to the C programming lan- guage. A standard math library is available by command line option. If requested, the math library is defined before processing any files. bc starts by processing code from all the files listed on the command line in the order listed. After all files have been processed, bc reads from the standard input. All code is executed as it is read. (If a file contains a command to halt the processor, bc will never read from the standard input.)"


what I'd call a hack, but given that you're only processing hour values, you can do

 hour=08
 echo $(( ${hour#0} +1 ))
 9
 hour=10 
 echo $(( ${hour#0} +1))
 11

with little risk.

IHTH.


How about sed?

hour=`echo $hour|sed -e "s/^0*//g"`

The leading 0 is leading to bash trying to interpret your number as an octal number, but octal numbers are 0-7, and 8 is thus an invalid token.

If I were you, I would add some logic to remove a leading 0, add one, and re-add the leading 0 if the result is < 10.


See ARITHMETIC EVALUATION in man bash:

Constants with a leading 0 are interpreted as octal numbers.

You can remove the leading zero by parameter expansion:

hour=${hour#0}

or force base-10 interpretation:

$((10#$hour + 1))

Since hours are always positive, and always 2 digits, you can set a 1 in front of it and subtract 100:

echo $((1$hour+1-100))

which is equivalent to

echo $((1$hour-99))

Be sure to comment such gymnastics. :)


Here's an easy way, albeit not the prettiest way to get an int value for a string.

hour=`expr $hour + 0`

Example

bash-3.2$ hour="08"
bash-3.2$ hour=`expr $hour + 0`
bash-3.2$ echo $hour
8

You could also use bc

hour=8
result=$(echo "$hour + 1" | bc)
echo $result
9