Une réponse claire a déjà été donnée par @charles Dufy et d'autres. Une solution bash pure utiliserait ce qui suit:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+[.,]?[0-9]*$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
Bien que pour les nombres réels, il n'est pas obligatoire d'avoir un nombre avant le point de radix .
Pour fournir un support plus complet des nombres flottants et de la notation scientifique (de nombreux programmes en C / Fortran ou bien exporteront float de cette façon), un ajout utile à cette ligne serait le suivant:
string="1.2345E-67"
if [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]?-?[0-9]+$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
Menant ainsi à un moyen de différencier les types de numéro, si vous recherchez un type spécifique:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+$ ]]
then
echo $string is an integer
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*$ ]]
then
echo $string is a float
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]-?[0-9]+$ ]]
then
echo $string is a scientific number
else
echo $string is not a number
fi
Remarque: Nous pourrions énumérer les exigences syntaxiques pour la notation décimale et scientifique, l'une étant d'autoriser la virgule comme point radix, ainsi que ".". Nous affirmerions alors qu'il ne doit y avoir qu'un seul point radix. Il peut y avoir deux signes +/- dans un flotteur [Ee]. J'ai appris quelques règles supplémentaires du travail d'Aulu et testé contre de mauvaises chaînes telles que '' '-' '-E-1' '0-0'. Voici mes outils regex / substring / expr qui semblent tenir le coup:
parse_num() {
local r=`expr "$1" : '.*\([.,]\)' 2>/dev/null | tr -d '\n'`
nat='^[+-]?[0-9]+[.,]?$' \
dot="${1%[.,]*}${r}${1##*[.,]}" \
float='^[\+\-]?([.,0-9]+[Ee]?[-+]?|)[0-9]+$'
[[ "$1" == $dot ]] && [[ "$1" =~ $float ]] || [[ "$1" =~ $nat ]]
} # usage: parse_num -123.456
test && echo "foo" && exit 0 || echo "bar" && exit 1
approche que vous utilisez peut avoir des effets secondaires imprévus - si l'écho échoue (la sortie est peut-être vers un FD fermé), leexit 0
sera ignoré et le code essaiera ensuite de le faireecho "bar"
. Si cela échoue également, la&&
condition échouera et ne s'exécutera même pasexit 1
! L'utilisation deif
déclarations réelles plutôt que&&
/||
est moins sujette à des effets secondaires inattendus.