extract numeric value from a string

21 views
Skip to first unread message

Smith

unread,
Jul 6, 2003, 11:57:39 PM7/6/03
to
Hi,

I've a variable with the following string:
(78.92%)

How do I get the value 78.92 and discard the (, %, and )?

Thanks and regards


Michael Wang

unread,
Jul 7, 2003, 12:10:09 AM7/7/03
to
In article <beaqdf$iig$1...@mawar.singnet.com.sg>,

Smith <som...@microsoft.com> wrote:
>Hi,
>
>I've a variable with the following string:
> (78.92%)
>
>How do I get the value 78.92 and discard the (, %, and )?

i="(78.92%)"
j=$(IFS='(%)'; print $i)
print $j
78.92
--
Michael Wang * http://www.unixlabplus.com/ * mw...@unixlabplus.com

Smith

unread,
Jul 7, 2003, 1:28:08 AM7/7/03
to
Thanks Michael,
It works.

Regards

"Michael Wang" <mw...@unixlabplus.com> wrote in message
news:Bo6Oa.49$bH.8...@news.uswest.net...

Tapani Tarvainen

unread,
Jul 7, 2003, 1:33:11 AM7/7/03
to
"Smith" <som...@microsoft.com> writes:

> I've a variable with the following string:
> (78.92%)
>
> How do I get the value 78.92 and discard the (, %, and )?

Assuming X='(78.92%)' initially and we want to end
up with X=78.92:

With ksh93:

X=${X//[()%]/}

With POSIX sh/ksh/bash &c:

X=${X#\(}
X=${X%%%*}

With any Bourne-compatible shell:

OLDIFS=$IFS
IFS='()%'
set -- $X
X=$1
IFS=$OLDIFS

--
Tapani Tarvainen

Stephane CHAZELAS

unread,
Jul 7, 2003, 3:14:44 AM7/7/03
to
Tapani Tarvainen wrote:
[...]

> Assuming X='(78.92%)' initially and we want to end
> up with X=78.92:
>
> With ksh93:
>
> X=${X//[()%]/}

or bash or zsh.

[...]
> With any Bourne-compatible shell:
(not zsh unless in sh compatibility mode)


>
> OLDIFS=$IFS
> IFS='()%'
> set -- $X
> X=$1
> IFS=$OLDIFS

X=$2

Note that POSIX doesn't say anything about the default value of
IFS, just that when unset, it's as if it were ' \t\n' (while
when empty, word splitting is disabled). So, the code above will
result in disabling word splitting if IFS was initially unset
(possible and even likely for a POSIX compliant shell even if
it's not the case in any implementation today).

It's also wise to disable filename generation when you do word
splitting (even if it's probably not an issue here).

OLDIFS=$IFS; ${IFS+":"} unset OLDIFS
IFS='()%'
set -f
set x $X
X=$3
IFS=$OLDIFS; ${OLDIFS+":"} unset IFS

(note that "unset" and "set -f" are not in every Bourne shell).

X=`expr "x$X" : 'x(\(.*\)%)$'`

X=`tr -d '()%' << EOF
$X
EOF`

--
Stéphane

Tapani Tarvainen

unread,
Jul 7, 2003, 3:45:54 AM7/7/03
to
Stephane CHAZELAS <stephane...@yahoo.fr> writes:

> > OLDIFS=$IFS
> > IFS='()%'
> > set -- $X
> > X=$1
> > IFS=$OLDIFS

> X=$2

It has to be $1 with the supposedly-Bourne /usr/old/bin/sh
in HP-UX 11.11, as well as with SunOS 5.8 /bin/sh.
Which sh needs $2?

> Note that POSIX doesn't say anything about the default value of
> IFS, just that when unset, it's as if it were ' \t\n' (while
> when empty, word splitting is disabled). So, the code above will
> result in disabling word splitting if IFS was initially unset

True.

> It's also wise to disable filename generation when you do word
> splitting (even if it's probably not an issue here).
>
> OLDIFS=$IFS; ${IFS+":"} unset OLDIFS
> IFS='()%'
> set -f
> set x $X
> X=$3
> IFS=$OLDIFS; ${OLDIFS+":"} unset IFS

Using x instead of -- is a good point, not all sh's understand --,
but again, I get it in $2 instead of $3 (in HPUX and SunOS).
If some shell puts it in $3, perhaps

set "" $X
X=$2$3

would be better, or does that fail in some situation as well?

> (note that "unset" and "set -f" are not in every Bourne shell).

Yeah. Portability is tough...

--
Tapani Tarvainen

Stephane CHAZELAS

unread,
Jul 7, 2003, 5:10:55 AM7/7/03
to
Tapani Tarvainen wrote:
>> > OLDIFS=$IFS
>> > IFS='()%'
>> > set -- $X
>> > X=$1
>> > IFS=$OLDIFS
>
>> X=$2
>
> It has to be $1 with the supposedly-Bourne /usr/old/bin/sh
> in HP-UX 11.11, as well as with SunOS 5.8 /bin/sh.
> Which sh needs $2?
[...]

at least POSIX ones and ash. You're right about Bourne ones even
if I wouldn't bet all flavours behave that way.

empty fields are not removed with POSIX shells unless when
enclosed between IFS white spaces (" ", "\t" or "\n" when they
are in IFS). Exception is ksh93 where the trailing one is
removed:

A=":A:" IFS=":"
set $A

results in only two fields ("" and "A"). I asked ast-developers
wether it was a bug or feature but got no answer.

--
Stéphane

Reply all
Reply to author
Forward
0 new messages