Четкий ответ уже дали @charles Dufy и другие. Чистое решение Bash будет использовать следующее:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+[.,]?[0-9]*$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
Хотя для действительных чисел не обязательно иметь число перед точкой ось .
Чтобы обеспечить более полную поддержку плавающих чисел и научных обозначений (многие программы на C / Fortran или иначе будут экспортировать float таким способом), полезным дополнением к этой строке будет следующее:
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
Таким образом, можно найти способ различать типы чисел, если вы ищете какой-либо конкретный тип:
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
Примечание: мы могли бы перечислить синтаксические требования для десятичной и научной нотации, одна из которых заключается в том, чтобы использовать запятую как точку отсчета, а также ".". Мы бы тогда утверждали, что должна быть только одна такая точка радиуса. В плавающем [Ee] может быть два знака +/-. Я узнал еще несколько правил из работы Аулу и проверил на наличие плохих строк, таких как '' '-' '-E-1' '0-0'. Вот мои инструменты regex / substring / expr, которые, кажется, удерживают:
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
вами подхода могут быть некоторые непреднамеренные побочные эффекты - если эхо не выполнится (возможно, вывод на закрытый FD),exit 0
он будет пропущен, а затем попытается выполнить кодecho "bar"
. Если и при этом&&
произойдет сбой, условие не будет выполнено и даже не выполнитсяexit 1
! Использование реальныхif
утверждений, а не&&
/||
менее подвержено неожиданным побочным эффектам.