Re: value too great for base (error token is "0008")

2009-11-04 Thread Greg Wooledge
On Tue, Nov 03, 2009 at 05:37:45PM -0700, Bob Proulx wrote:
> Dobromir Romankiewicz wrote:
> > bash: 0008: value too great for base (error token is "0008").

> Numbers with leading zeros are read as octal constants.  Octal is
> composed of '0' through '7'.  The number '8' is too large to be an
> octal number.
> 
>   $ echo $((0008))
>   bash: 0008: value too great for base (error token is "0008")
> 
> To have the number read as a decimal number the leading zeros must be
> removed.
> 
>   $ echo $((8))
>   8

If removing the leading zeroes would be difficult for you, then you can
force the arithmetic expression to use base 10 by prefixing the variable
with "10#".  Thus:

  month=$(date +%m) # Can produce "08" etc.
  next_month=$(( (10#$month == 12) ? 1 : 10#$month+1 ))
  echo $next_month

On the other hand, removing a single leading zero is not difficult:

  month=$(date +%m) month=${month#0}   # Removing leading 0
  next_month=$(( ($month == 12) ? 1 : $month+1 ))

Removing multiple leading zeroes, however, requires either a loop, or the
use of extended globs.  A variant of this question (removing leading/trailing
spaces) appears at .  Although it
looks like someone removed my loop solution... grrr.

> Note also that the use of $[expression] for $((expression)) is
> documented as deprecated and to be removed in a future version.
> Better to use $((expression)) instead.

$((...)) is also POSIX-compliant.  Please do switch.




Re: value too great for base (error token is "0008")

2009-11-04 Thread Eric Blake
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

According to Greg Wooledge on 11/4/2009 6:23 AM:
> On the other hand, removing a single leading zero is not difficult:
> 
>   month=$(date +%m) month=${month#0}   # Removing leading 0

Not portable.  Assigning the same variable twice in the same statement has
different order of operations in some shells.  Use:

month=$(date +%m); month=${month#0}

instead.

>   next_month=$(( ($month == 12) ? 1 : $month+1 ))
> 
> Removing multiple leading zeroes, however, requires either a loop, or the
> use of extended globs.

Not true.  You can do it via POSIX and without a loop by using an
intermediate variable:

foo=00081
bar=${foo%%[!0]*}
foo=${foo#$bar}}

- --
Don't work too hard, make some time for fun as well!

Eric Blake e...@byu.net
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrxgn0ACgkQ84KuGfSFAYDyCACg0suH5IFGv+4dOe5Bf3kyBExR
R20AoM+U/AP6tqrF0QpEEYWgvjfx2m+H
=aC1b
-END PGP SIGNATURE-




Re: value too great for base (error token is "0008")

2009-11-04 Thread Chris F.A. Johnson
On Wed, 4 Nov 2009, Eric Blake wrote:
> According to Greg Wooledge on 11/4/2009 6:23 AM:
> > On the other hand, removing a single leading zero is not difficult:
> > 
> >   month=$(date +%m) month=${month#0}   # Removing leading 0
> 
> Not portable.  Assigning the same variable twice in the same statement has
> different order of operations in some shells.  Use:
> 
> month=$(date +%m); month=${month#0}
> 
> instead.
> 
> >   next_month=$(( ($month == 12) ? 1 : $month+1 ))
> > 
> > Removing multiple leading zeroes, however, requires either a loop, or the
> > use of extended globs.
> 
> Not true.  You can do it via POSIX and without a loop by using an
> intermediate variable:
> 
> foo=00081
> bar=${foo%%[!0]*}
> foo=${foo#$bar}}

   Or even without an intermediate variable:

foo=${foo#${foo%%[!0]*}}

   (Though I prefer the variable for legibility.)

-- 
   Chris F.A. Johnson, webmaster 
   ===
   Author:
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
   Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)