Differences between revisions 1 and 2
Revision 1 as of 2007-05-02 23:46:43
Size: 1429
Editor: redondos
Comment:
Revision 2 as of 2007-05-07 18:02:07
Size: 1556
Editor: GreyCat
Comment: [0-9]* before the decimal, not [0-9]+, so we can have .5 as a number. This requires checking non-blank-ness.
Deletions are marked like this. Additions are marked like this.
Line 26: Line 26:
if [[ $foo =~ ^[-+]?[0-9]+\(\.[0-9]+\)?$ ]]; then if [[ $foo && $foo =~ ^[-+]?[0-9]*\(\.[0-9]+\)?$ ]]; then
Line 36: Line 36:
if echo "$foo" | egrep '^[-+]?[0-9]+(\.[0-9]+)?$' >/dev/null; then if test "$foo" && echo "$foo" | egrep '^[-+]?[0-9]*(\.[0-9]+)?$' >/dev/null; then
Line 43: Line 43:
Note that the parentheses in the {{{egrep}}} regular expression don't require backslashes in front of them, whereas the ones in the bash3 command do. Note that the parentheses in the {{{egrep}}} regular expression don't require backslashes in front of them, whereas the ones in the bash3 command do.  Also, the leading test of {{{"$foo"}}} (in both versions) is to ensure that it is not an empty string.

Anchor(faq54)

How can I tell whether a variable contains a valid number?

First, you have to define what you mean by "number". The most common case seems to be that, when people ask this, they actually mean "a non-negative integer, with no leading + sign".

if [[ $foo = *[^0-9]* ]]; then
   echo "'$foo' has a non-digit somewhere in it"
else
   echo "'$foo' is strictly numeric"
fi

This can be done in Korn and legacy Bourne shells as well, using case:

case "$foo" in
    *[!0-9]*) echo "'$foo' has a non-digit somewhere in it" ;;
    *) echo "'$foo' is strictly numeric" ;;
esac

If what you actually mean is "a valid floating-point number" or something else more complex, then you might prefer to use a regular expression. Bash version 3 and above have regular expression support in the [[ command:

if [[ $foo && $foo =~ ^[-+]?[0-9]*\(\.[0-9]+\)?$ ]]; then
    echo "'$foo' looks rather like a number"
else
    echo "'$foo' doesn't look particularly numeric to me"
fi

If you don't have bash version 3, then you would use egrep:

if test "$foo" && echo "$foo" | egrep '^[-+]?[0-9]*(\.[0-9]+)?$' >/dev/null; then
    echo "'$foo' might be a number"
else
    echo "'$foo' might not be a number"
fi

Note that the parentheses in the egrep regular expression don't require backslashes in front of them, whereas the ones in the bash3 command do. Also, the leading test of "$foo" (in both versions) is to ensure that it is not an empty string.

BashFAQ/054 (last edited 2022-04-19 05:23:33 by emanuele6)