Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Remove leading zeros

23 views
Skip to first unread message

Spiros Bousbouras

unread,
Feb 9, 2009, 3:25:57 PM2/9/09
to
Is there a way to remove leading zeros from a
shell variable using only shell built-ins and with
no loops?

OldSchool

unread,
Feb 9, 2009, 3:29:54 PM2/9/09
to

OldSchool

unread,
Feb 9, 2009, 3:32:41 PM2/9/09
to
On Feb 9, 3:25 pm, Spiros Bousbouras <spi...@gmail.com> wrote:

if the variable contains only digits, and doesn't overflow, then

#!/usr/bin/ksh
typeset -i x
y="00123"
eval x=$y
echo $y $x

Spiros Bousbouras

unread,
Feb 9, 2009, 3:41:01 PM2/9/09
to

Doesn't work, it interprets y as octal.

pk

unread,
Feb 9, 2009, 3:55:45 PM2/9/09
to

With bash, you can do

$ var=00003701; echo $((10#$var))
3701

$ shopt -s extglob; var=00004402; echo ${var##+(0)}
4402


Glenn Jackman

unread,
Feb 9, 2009, 4:21:28 PM2/9/09
to

for bash:
shopt -s extglob
x=000876
y=${x##+(0)}
printf "%s\n" $x $y

--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous

Janis Papanagnou

unread,
Feb 9, 2009, 4:31:47 PM2/9/09
to
pk wrote:
> On Monday 9 February 2009 21:25, Spiros Bousbouras wrote:
>
>
>>Is there a way to remove leading zeros from a
>>shell variable using only shell built-ins and with
>>no loops?
>
>
> With bash, you can do

Also ksh...

>
> $ var=00003701; echo $((10#$var))
> 3701

$ var=00003701; echo $((10#$var))
3701

>
> $ shopt -s extglob; var=00004402; echo ${var##+(0)}
> 4402

$ var=00004402; echo ${var##+(0)}
4402


But mind that whether the result is desired depends on the
requirements...

$ var=0000; echo $((10#$var)) # zero
0

$ var=0000; echo ${var##+(0)} # empty

Janis

Spiros Bousbouras

unread,
Feb 9, 2009, 4:38:28 PM2/9/09
to

Another BASH solution:

a=0000gh
[[ $a =~ '^0*(.*)' ]]
a="${BASH_REMATCH[1]}"

Ed Morton

unread,
Feb 9, 2009, 4:44:41 PM2/9/09
to

$ $SHELL --version
GNU bash, version 3.2.39(20)-release (i686-pc-cygwin)
Copyright (C) 2007 Free Software Foundation, Inc.
$ a=0000gh
$ [[ $a =~ '^0*(.*)' ]]
$ a="${BASH_REMATCH[1]}"
$ echo "<$a>"
<>
$

$ a=0000gh
$ a=${a##+(0)}
$ echo "<$a>"
<gh>

Why are you proposing solutions to your own questions, though?

Ed.

Tin...@teranews.com

unread,
Feb 9, 2009, 4:52:19 PM2/9/09
to

In bash

a="00099"
printf "%d\n" $a

pk

unread,
Feb 9, 2009, 4:55:48 PM2/9/09
to

Did you try that one?

$ var=0077
$ printf "%d\n" $var
63

$ var=00099
$ printf "%d\n" $var
bash: printf: 00099: invalid number
0

pk

unread,
Feb 9, 2009, 3:55:45 PM2/9/09
to
On Monday 9 February 2009 21:25, Spiros Bousbouras wrote:

With bash, you can do

$ var=00003701; echo $((10#$var))

pk

unread,
Feb 9, 2009, 3:55:45 PM2/9/09
to
On Monday 9 February 2009 21:25, Spiros Bousbouras wrote:

With bash, you can do

Spiros Bousbouras

unread,
Feb 9, 2009, 5:08:17 PM2/9/09
to
On 9 Feb, 21:44, Ed Morton <mortons...@gmail.com> wrote:
> On Feb 9, 3:38 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
>
> > On 9 Feb, 20:25, Spiros Bousbouras <spi...@gmail.com> wrote:
>
> > > Is there a way to remove leading zeros from a
> > > shell variable using only shell built-ins and with
> > > no loops?
>
> > Another BASH solution:
>
> > a=0000gh
> > [[ $a =~ '^0*(.*)' ]]
> > a="${BASH_REMATCH[1]}"
>
> $ $SHELL --version
> GNU bash, version 3.2.39(20)-release (i686-pc-cygwin)
> Copyright (C) 2007 Free Software Foundation, Inc.
> $ a=0000gh
> $ [[ $a =~ '^0*(.*)' ]]
> $ a="${BASH_REMATCH[1]}"
> $ echo "<$a>"
> <>

So the above version has a bug?

> $ a=0000gh
> $ a=${a##+(0)}
> $ echo "<$a>"
> <gh>

After you do shopt -s extglob I presume.

> Why are you proposing solutions to your own questions, though?

As opposed to what , keeping it to myself ?

Dave B

unread,
Feb 9, 2009, 4:03:47 PM2/9/09
to
Spiros Bousbouras wrote:

With bash, you can do

$ var=00003701; echo $((10#$var))
3701

$ shopt -s extglob; var=00004402; echo ${var##+(0)}
4402

--
sh -c 'a123=$4;b=$2;j=4464346045754551;h=$1;r=4165722075063752;s=$3;
while [ "$r" != "" ];do x=0;y=;w=${#h};while [ $x -lt $(($w-1)) ];do
y=$y?;x=$((x+1));done;o=$o$s${h%$y}${j%$y}${r%$y};r=${r#?};j=${j#?};
h=${h#?};done;eval "$a123 $b$o$b"' sh 1111111111101110 \' '\' printf

David W. Hodgins

unread,
Feb 9, 2009, 6:09:17 PM2/9/09
to
On Mon, 09 Feb 2009 16:31:47 -0500, Janis Papanagnou <janis_pa...@hotmail.com> wrote:

> $ var=00003701; echo $((10#$var))
> 3701

Thanks. I didn't recognize the above syntax, and had to dig a bit to
figure out what it is.

For the benefit of any others reading this, from info bash, the $(( indicates
arithmetic expansion and the 10# indicates that what follows the # is a base
10 number.

Regards, Dave Hodgins

--
Change nomail.afraid.org to ody.ca to reply by email.
(nomail.afraid.org has been set up specifically for
use in usenet. Feel free to use it yourself.)

Ed Morton

unread,
Feb 10, 2009, 10:10:11 AM2/10/09
to
On Feb 9, 4:08 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
> On 9 Feb, 21:44, Ed Morton <mortons...@gmail.com> wrote:
>
>
>
> > On Feb 9, 3:38 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
>
> > > On 9 Feb, 20:25, Spiros Bousbouras <spi...@gmail.com> wrote:
>
> > > > Is there a way to remove leading zeros from a
> > > > shell variable using only shell built-ins and with
> > > > no loops?
>
> > > Another BASH solution:
>
> > > a=0000gh
> > > [[ $a =~ '^0*(.*)' ]]
> > > a="${BASH_REMATCH[1]}"
>
> > $ $SHELL --version
> > GNU bash, version 3.2.39(20)-release (i686-pc-cygwin)
> > Copyright (C) 2007 Free Software Foundation, Inc.
> > $ a=0000gh
> > $ [[ $a =~ '^0*(.*)' ]]
> > $ a="${BASH_REMATCH[1]}"
> > $ echo "<$a>"
> > <>
>
> So the above version has a bug?

I don't know. Does it or does the proposed solution only work with
some version(s) of bash?

> > $ a=0000gh
> > $ a=${a##+(0)}
> > $ echo "<$a>"
> > <gh>
>
> After you do shopt -s extglob I presume.
>
> > Why are you proposing solutions to your own questions, though?
>
> As opposed to what , keeping it to myself ?

As opposed to either:

a) not asking the question, or
b) when asking the question stating you have a specific solution
already but you aren't happy with it for reason XXXX and you're
looking for a different solution that's faster or more concise or
whatever so we don't waste time recreating it or proposing solutions
that don't have the characteristics you want.

Ed.

Spiros Bousbouras

unread,
Feb 10, 2009, 11:21:22 AM2/10/09
to
On 10 Feb, 15:10, Ed Morton <mortons...@gmail.com> wrote:
> On Feb 9, 4:08 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
>
> > On 9 Feb, 21:44, Ed Morton <mortons...@gmail.com> wrote:
>
> > > On Feb 9, 3:38 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
>
> > > > On 9 Feb, 20:25, Spiros Bousbouras <spi...@gmail.com> wrote:
>
> > > > > Is there a way to remove leading zeros from a
> > > > > shell variable using only shell built-ins and with
> > > > > no loops?
>
> > > > Another BASH solution:
>
> > > > a=0000gh
> > > > [[ $a =~ '^0*(.*)' ]]
> > > > a="${BASH_REMATCH[1]}"
>
> > > $ $SHELL --version
> > > GNU bash, version 3.2.39(20)-release (i686-pc-cygwin)
> > > Copyright (C) 2007 Free Software Foundation, Inc.
> > > $ a=0000gh
> > > $ [[ $a =~ '^0*(.*)' ]]
> > > $ a="${BASH_REMATCH[1]}"
> > > $ echo "<$a>"
> > > <>
>
> > So the above version has a bug?
>
> I don't know. Does it or does the proposed solution only work with
> some version(s) of bash?

I'm sure it wasn't in BASH from the beginning so it only works
on some versions. But I tested on version 3.1.17 which is
earlier than yours so something else is going on. After some
googling I found E14 in
http://www.faqs.org/faqs/unix-faq/shell/bash There is the
compat31 shopt option which restores the earlier behaviour:
http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-039

Even after reading E14 it's not clear to me why the BASH people
decided to change the behaviour and I'm sure it made life
difficult for a lot of people. Based on what I read the
following will work on both my version and yours:

regexp='^0*(.*)'
a=0000gh
[[ $a =~ $regexp ]]
a="${BASH_REMATCH[1]}"

> > > Why are you proposing solutions to your own questions, though?
>
> > As opposed to what , keeping it to myself ?
>
> As opposed to either:
>
> a) not asking the question, or
> b) when asking the question stating you have a specific solution
> already but you aren't happy with it for reason XXXX and you're
> looking for a different solution that's faster or more concise or
> whatever so we don't waste time recreating it or proposing solutions
> that don't have the characteristics you want.

The answer is obviously that I only thought of my solution after I
made the OP.


Stephane CHAZELAS

unread,
Feb 10, 2009, 3:28:05 PM2/10/09
to
2009-02-9, 12:25(-08), Spiros Bousbouras:

> Is there a way to remove leading zeros from a
> shell variable using only shell built-ins and with
> no loops?

A standard solution:

case $var in
(*[!0]*)
tmp=${var%%[!0]*}
var=${var#"$tmp"};;
("") ;;
(*) var=0
esac

--
Stéphane

Stephane CHAZELAS

unread,
Feb 10, 2009, 3:40:29 PM2/10/09
to
2009-02-09, 22:31(+01), Janis Papanagnou:

> pk wrote:
>> On Monday 9 February 2009 21:25, Spiros Bousbouras wrote:
>>
>>
>>>Is there a way to remove leading zeros from a
>>>shell variable using only shell built-ins and with
>>>no loops?
>>
>>
>> With bash, you can do
>
> Also ksh...

And of course as usual, what ksh or bash can do, so can zsh.

[...]


>> $ shopt -s extglob; var=00004402; echo ${var##+(0)}
>> 4402
>
> $ var=00004402; echo ${var##+(0)}
> 4402

You want setopt kshglob for zsh to recognise those extended ksh
globbing patterns. Or use zsh extended patterns:

setopt extendedglob
echo ${var##0#}

>
> But mind that whether the result is desired depends on the
> requirements...
>
> $ var=0000; echo $((10#$var)) # zero
> 0

$ var=1+2; echo $((10#$var))'
3
$ var=010+020; echo $((10#$var))'
26

With zsh:

setopt extendedglob
echo ${var/(#m)<->/$((MATCH))}

>
> $ var=0000; echo ${var##+(0)} # empty

Now try that with any shell other than zsh and this value of
$var:
var=000/*/*/*/../../../*/*/*/../../../*/*/*

(not on a production server though!)

Variables should be quoted.

--
Stéphane

Spiros Bousbouras

unread,
Feb 10, 2009, 3:51:20 PM2/10/09
to
On 10 Feb, 20:28, Stephane CHAZELAS <stephane_chaze...@yahoo.fr>
wrote:

This takes first price ! But why not

case $var in


*[!0]*)
tmp=${var%%[!0]*}
var=${var#"$tmp"};;

"") ;;
*) var=0
esac

What is the role of the opening parenthesis?

Spiros Bousbouras

unread,
Feb 10, 2009, 3:56:00 PM2/10/09
to
On 10 Feb, 20:40, Stephane CHAZELAS <stephane_chaze...@yahoo.fr>
wrote:

>
> Now try that with any shell other than zsh and this value of
> $var:
> var=000/*/*/*/../../../*/*/*/../../../*/*/*
>
> (not on a production server though!)
>
> Variables should be quoted.

Try what exactly? Your standard method on BASH works
with the above value of var. Which variables should
be quoted?

Stephane CHAZELAS

unread,
Feb 10, 2009, 3:57:04 PM2/10/09
to
2009-02-10, 12:51(-08), Spiros Bousbouras:

legibility, better integration with text editors. Having matched
parenthesis avoid some syntax problems with some shells in some
circumstances.


--
Stéphane

Spiros Bousbouras

unread,
Feb 10, 2009, 3:59:37 PM2/10/09
to
On 10 Feb, 20:57, Stephane CHAZELAS <stephane_chaze...@yahoo.fr>
wrote:

> 2009-02-10, 12:51(-08), Spiros Bousbouras:
>
>
>
> > On 10 Feb, 20:28, Stephane CHAZELAS <stephane_chaze...@yahoo.fr>
> > wrote:
> >> 2009-02-9, 12:25(-08), Spiros Bousbouras:
>
> >> > Is there a way to remove leading zeros from a
> >> > shell variable using only shell built-ins and with
> >> > no loops?
>
> >> A standard solution:
>
> >> case $var in
> >> (*[!0]*)
> >> tmp=${var%%[!0]*}
> >> var=${var#"$tmp"};;
> >> ("") ;;
> >> (*) var=0
> >> esac
>
> > This takes first price ! But why not
>
> > case $var in
> > *[!0]*)
> > tmp=${var%%[!0]*}
> > var=${var#"$tmp"};;
> > "") ;;
> > *) var=0
> > esac
>
> > What is the role of the opening parenthesis?
>
> Having matched
> parenthesis avoid some syntax problems with some shells in some
> circumstances.

For example ?

Stephane CHAZELAS

unread,
Feb 10, 2009, 4:22:37 PM2/10/09
to
2009-02-10, 12:59(-08), Spiros Bousbouras:
[...]

>> >> case $var in
>> >> (*[!0]*)
[...]

>> > This takes first price ! But why not
>>
>> > case $var in
>> > *[!0]*)
[...]

>> Having matched
>> parenthesis avoid some syntax problems with some shells in some
>> circumstances.
>
> For example ?

$ pdksh -c 'echo $(case a in *) echo $a;; esac)'
pdksh: syntax error: `;;' unexpected

mksh, posh, zsh, bash are also affected.

ash, ksh93 are not. bash 4 will not be.

--
Stéphane

0 new messages