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
i="(78.92%)"
j=$(IFS='(%)'; print $i)
print $j
78.92
--
Michael Wang * http://www.unixlabplus.com/ * mw...@unixlabplus.com
Regards
"Michael Wang" <mw...@unixlabplus.com> wrote in message
news:Bo6Oa.49$bH.8...@news.uswest.net...
> 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
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
> > 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
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