Как проверить, является ли переменная числом в Bash?
Я просто не могу понять, как сделать так, чтобы аргумент, передаваемый моему сценарию, был числом или нет.
Все, что я хочу сделать, это что-то вроде этого:
test *isnumber* $1 && VAR=$1 || echo "need a number"
Любая помощь?
42 ответа
Один из подходов заключается в использовании регулярного выражения, например, так:
re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
echo "error: Not a number" >&2; exit 1
fi
Если значение не обязательно является целым числом, попробуйте соответствующим образом изменить регулярное выражение; например:
^[0-9]+([.][0-9]+)?$
... или для обработки чисел со знаком:
^[+-]?[0-9]+([.][0-9]+)?$
Без башмизмов (работает даже в Системе В Ш),
case $string in
''|*[!0-9]*) echo bad ;;
*) echo good ;;
esac
Это отклоняет пустые строки и строки, содержащие не-цифры, принимая все остальное.
Отрицательные числа или числа с плавающей точкой требуют дополнительной работы. Идея состоит в том, чтобы исключить -
/ .
в первый "плохой" шаблон и добавьте больше "плохих" шаблонов, содержащих их неуместное использование (?*-*
/ *.*.*
)
Следующее решение может также использоваться в базовых оболочках, таких как Bourne, без необходимости использования регулярных выражений. В основном любые операции вычисления числовых значений, использующие не числа, приведут к ошибке, которая будет неявно рассматриваться как ложная в оболочке:
"$var" -eq "$var"
как в:
#!/bin/bash
var=a
if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
echo number
else
echo not a number
fi
Вы можете также проверить на $? код возврата операции, которая является более явной:
[ -n "$var" ] && ["$var" -eq "$var"] 2>/dev/null
if [ $? -ne 0 ]; then
echo $var is not number
fi
Перенаправление стандартной ошибки предназначено для того, чтобы скрыть сообщение "ожидается целочисленное выражение", которое распечатывает bash, если у нас нет числа.
ПРЕДОСТЕРЕЖЕНИЯ (благодаря комментариям ниже):
- Числа с десятичными точками не идентифицируются как действительные "числа"
- С помощью
[[ ]]
вместо[ ]
всегда буду оцениватьtrue
- Большинство небашевых оболочек всегда будет оценивать это выражение как
true
- Поведение в Bash недокументировано и поэтому может меняться без предупреждения
- Если значение включает пробелы после числа (например, "1 a"), возникает ошибка, например
bash: [[: 1 a: syntax error in expression (error token is "a")
- Если значение совпадает с var-name (например, i = "i"), выдает ошибку, например
bash: [[: i: expression recursion level exceeded (error token is "i")
Никто не предложил расширенное сопоставление с образцом в bash:
[[ $1 == ?(-)+([0-9]) ]] && echo "$1 is an integer"
Баш регулярное выражение против Баша расширения параметра
Поскольку ответ Чарльза Даффи работает, но использует только регулярное выражение bash, и я знаю, что это будет медленно, я хотел бы показать другой способ, используя только расширение параметра bash:
Только для положительных целых чисел:
is_num() { [ "$1" ] && [ -z "${1//[0-9]}" ] ;}
Для целых чисел:
is_num() {
local chk=${1#[+-]};
[ "$chk" ] && [ -z "${chk//[0-9]}" ]
}
Затем для плавания:
is_num() {
local chk=${1#[+-]};
chk=${chk/.}
[ "$chk" ] && [ -z "${chk//[0-9]}" ]
}
Для соответствия первоначальному запросу:
set -- "foo bar"
is_num "$1" && VAR=$1 || echo "need a number"
need a number
set -- "+3.141592"
is_num "$1" && VAR=$1 || echo "need a number"
echo $VAR
+3.141592
А теперь небольшое сравнение:
Есть такая же проверка, основанная на ответе Чарльза Даффи:
cdIs_num() {
local re='^[+-]?[0-9]+([.][0-9]+)?$';
[[ $1 =~ $re ]]
}
Некоторые тесты:
if is_num foo;then echo It\'s a number ;else echo Not a number;fi
Not a number
if cdIs_num foo;then echo It\'s a number ;else echo Not a number;fi
Not a number
if is_num 25;then echo It\'s a number ;else echo Not a number;fi
It's a number
if cdIs_num 25;then echo It\'s a number ;else echo Not a number;fi
It's a number
if is_num 3+4;then echo It\'s a number ;else echo Not a number;fi
Not a number
if cdIs_num 3+4;then echo It\'s a number ;else echo Not a number;fi
Not a number
if is_num 3.1415;then echo It\'s a number ;else echo Not a number;fi
It's a number
if cdIs_num 3.1415;then echo It\'s a number ;else echo Not a number;fi
It's a number
Хорошо, это нормально. А теперь сколько времени займет все это (на моем raspberry pi):
time for i in {1..1000};do is_num +3.14159265;done
real 0m2.476s
user 0m1.235s
sys 0m0.000s
Затем с помощью регулярных выражений:
time for i in {1..1000};do cdIs_num +3.14159265;done
real 0m4.363s
user 0m2.168s
sys 0m0.000s
Это проверяет, является ли число неотрицательным целым числом и является ли оно независимым от оболочки (то есть без башизмов), и использует только встроенные функции оболочки:
[ -z "${num##[0-9]*}" ] && echo "is a number" || echo "is not a number";
НО НЕПРАВИЛЬНО.
Как прокомментировал и предположил Джилс в своем ответе, это правильный способ сделать это, используя шаблоны оболочки.
[ ! -z "${num##*[!0-9]*}" ] && echo "is a number" || echo "is not a number";
Я удивлен решениями, непосредственно разбирающими числовые форматы в оболочке. shell не очень подходит для этого, поскольку является DSL для управления файлами и процессами. Немного ниже парсеры чисел, например:
isdecimal() {
# filter octal/hex/ord()
num=$(printf '%s' "$1" | sed "s/^0*\([1-9]\)/\1/; s/'/^/")
test "$num" && printf '%f' "$num" >/dev/null 2>&1
}
Измените "%f" на тот формат, который вам требуется.
Я смотрел на ответы и... понял, что никто не думал о числах FLOAT (с точкой)!
Использование grep тоже замечательно.
-E означает расширенное регулярное выражение
-q означает тихий (не повторяет)
-qE является комбинацией обоих.
Чтобы проверить прямо в командной строке:
$ echo "32" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is: 32
$ echo "3a2" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is empty (false)
$ echo ".5" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer .5
$ echo "3.2" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is 3.2
Использование в скрипте bash:
check=`echo "$1" | grep -E ^\-?[0-9]*\.?[0-9]+$`
if [ "$check" != '' ]; then
# it IS numeric
echo "Yeap!"
else
# it is NOT numeric.
echo "nooop"
fi
Чтобы соответствовать JUST целым числам, используйте это:
# change check line to:
check=`echo "$1" | grep -E ^\-?[0-9]+$`
Просто продолжение до @mary. Но из-за того, что у меня недостаточно представителей, я не смог опубликовать это как комментарий к этому сообщению. В любом случае, вот что я использовал:
isnum() { awk -v a="$1" 'BEGIN {print (a == a + 0)}'; }
Функция вернет "1", если аргумент является числом, в противном случае вернет "0". Это работает как для целых чисел, так и для чисел с плавающей точкой. Использование это что-то вроде:
n=-2.05e+07
res=`isnum "$n"`
if [ "$res" == "1" ]; then
echo "$n is a number"
else
echo "$n is not a number"
fi
Для моей проблемы мне нужно было только убедиться, что пользователь случайно не введет какой-то текст, поэтому я старался сделать его простым и читабельным
isNumber() {
(( $1 )) 2>/dev/null
}
Согласно справочной странице это в значительной степени делает то, что я хочу
Если значение выражения не равно нулю, возвращаемое состояние равно 0
Чтобы предотвратить неприятные сообщения об ошибках для строк, которые могут быть числами, я игнорирую вывод ошибок
$ (( 2s ))
bash: ((: 2s: value too great for base (error token is "2s")
Это может быть достигнуто с помощью grep
чтобы увидеть, соответствует ли рассматриваемая переменная расширенному регулярному выражению.
Тест целое число 1120
:
yournumber=1120
if [ $(echo "$yournumber" | grep -qE '^[0-9]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
Выход: Valid number.
Тест не целое число 1120a
:
yournumber=1120a
if [ $(echo "$yournumber" | grep -qE '^[0-9]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
Выход: Error: not a number.
объяснение
grep
,-E
Переключатель позволяет нам использовать расширенное регулярное выражение'^[0-9]+$'
, Это регулярное выражение означает, что переменная должна только[]
содержать числа0-9
от нуля до девяти от^
начиная с$
конец переменной и должен иметь как минимум+
один персонажgrep
,-q
Тихий переключатель отключает любой выход независимо от того, находит ли он что-либо.$?
это статус выхода предыдущей выполненной команды. Статус выхода0
означает успех, а все большее означает ошибку.grep
команда имеет статус выхода0
если он найдет совпадение и1
когда это не так;$()
является подоболочкой, которая позволяет нам выполнить другую команду и затем использовать вывод.
Так что все это вместе, в $()
под раковиной, мы echo
переменная $yournumber
а также |
передать это grep
который с -q
переключатель молча соответствует -E
расширенное регулярное выражение '^[0-9]+$'
выражение. Мы тогда echo
$?
статус выхода, который будет 0
если grep
успешно нашли совпадение и 1
если это не так.
Теперь за пределами $()
Раковина и обратно в if
условно, мы берем вывод, либо 0
или же 1
от $()
недоработать и проверить, если это -ne
не равно "0"
, Если он не соответствует, статус выхода будет 1
который не соответствует "0"
, Тогда мы будем echo "Error: not a number."
, В случае совпадения выходной статус будет 0
который равен "0"
и в этом другом случае мы echo "Valid number."
,
Для поплавков или пар
Мы можем просто изменить регулярное выражение из '^[0-9]+$'
в '^[0-9]*+\.?[0-8]+$'
для поплавков или пар.
Тест поплавок 1120.01
:
yournumber=1120.01
if [ $(echo "$yournumber" | grep -qE '^[0-9]*+\.?[0-8]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
Выход: Valid number.
Тест поплавок 11.20.01
:
yournumber=11.20.01
if [ $(echo "$yournumber" | grep -qE '^[0-9]*+\.?[0-8]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
Выход: Error: not a number.
Для негативов
Чтобы разрешить отрицательные целые числа, просто измените регулярное выражение с '^[0-9]+$'
в '^\-?[0-9]+$'
,
Чтобы разрешить отрицательные числа с плавающей запятой или двойные числа, просто измените регулярное выражение с '^[0-9]*+\.?[0-8]+$'
в '^\-?[0-9]*+\.?[0-8]+$'
,
test -z "${i//[0-9]}" && echo digits || echo no no no
${i//[0-9]}
заменяет любую цифру в значении $i
с пустой строкой, см. man -P 'less +/parameter\/' bash
, -z
проверяет, имеет ли полученная строка нулевую длину.
если вы также хотите исключить случай, когда $i
пусто, вы можете использовать одну из этих конструкций:
test -n "$i" && test -z "${i//[0-9]}" && echo digits || echo not a number
[[ -n "$i" && -z "${i//[0-9]}" ]] && echo digits || echo not a number
Старый вопрос, но я просто хотел придерживаться своего решения. Этот не требует каких-либо странных трюков с ракушками или полагается на то, чего не было всегда.
if [ -n "$(printf '%s\n' "$var" | sed 's/[0-9]//g')" ]; then
echo 'is not numeric'
else
echo 'is numeric'
fi
По сути, он просто удаляет все цифры из входных данных, и если у вас осталась строка не нулевой длины, то это не было число.
Я бы попробовал это:
printf "%g" "$var" &> /dev/null
if [[ $? == 0 ]] ; then
echo "$var is a number."
else
echo "$var is not a number."
fi
Примечание: это распознает nan и inf как число.
Пока не могу комментировать, поэтому я добавлю свой собственный ответ, который является расширением ответа Гленна Джекмана с использованием сопоставления с шаблоном bash.
Моей первоначальной потребностью было идентифицировать числа и различать целые числа и числа с плавающей запятой. Определения функций вычитаются в:
function isInteger() {
[[ ${1} == ?(-)+([0-9]) ]]
}
function isFloat() {
[[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
Я использовал модульное тестирование (с shUnit2) для проверки работоспособности моих шаблонов:
oneTimeSetUp() {
int_values="0 123 -0 -123"
float_values="0.0 0. .0 -0.0 -0. -.0 \
123.456 123. .456 -123.456 -123. -.456
123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
}
testIsIntegerIsFloat() {
local value
for value in ${int_values}
do
assertTrue "${value} should be tested as integer" "isInteger ${value}"
assertFalse "${value} should not be tested as float" "isFloat ${value}"
done
for value in ${float_values}
do
assertTrue "${value} should be tested as float" "isFloat ${value}"
assertFalse "${value} should not be tested as integer" "isInteger ${value}"
done
}
Примечания: шаблон isFloat может быть изменен, чтобы быть более терпимым к десятичной запятой (@(.,)
) и символ E (@(Ee)
). Мои модульные тесты тестируют только значения, которые являются целочисленными или плавающими, но не содержат недопустимых входных данных
[[ $1 =~ ^-?[0-9]+$ ]] && echo "number"
Не забывай -
включить отрицательные числа!
Четкий ответ уже дали @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
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_03.html
Вы также можете использовать классы персонажей bash.
if [[ $VAR = *[[:digit:]]* ]]; then
echo "$VAR is numeric"
else
echo "$VAR is not numeric"
fi
Числа будут включать пробел, десятичную точку и "e" или "E" для числа с плавающей запятой.
Но если вы укажете шестнадцатеричное число в стиле C, то есть "0xffff" или "0XFFFF", [[:digit:]] вернет true. Здесь есть небольшая ловушка, bash позволяет вам делать что-то вроде "0xAZ00" и по-прежнему считать его цифрой (разве это не странная причуда компиляторов GCC, позволяющих использовать нотацию 0x для баз, отличных от 16???)
Возможно, вы захотите проверить "0x" или "0X" перед проверкой, является ли оно числовым, если ваш ввод абсолютно ненадежен, если вы не хотите принимать шестнадцатеричные числа. Это будет достигнуто путем:
if [[ ${VARIABLE:1:2} = "0x" ]] || [[ ${VARIABLE:1:2} = "0X" ]]; then echo "$VAR is not numeric"; fi
Самый простой способ - проверить, содержит ли он нецифровые символы. Вы заменяете все цифры на ничто и проверяете длину. Если есть длина, то это не число.
if [[ ! -n ${input//[0-9]/} ]]; then
echo "Input Is A Number"
fi
Я использую expr. Он возвращает ненулевое значение, если вы пытаетесь добавить ноль к нечисловому значению:
if expr -- "$number" + 0 > /dev/null 2>&1
then
echo "$number is a number"
else
echo "$number isn't a number"
fi
Может быть возможно использовать bc, если вам нужны нецелые числа, но я не верю bc
имеет совершенно такое же поведение. Добавление нуля к нечисленному номеру возвращает вас к нулю и также возвращает значение нуля. Может быть, вы можете объединить bc
а также expr
, использование bc
добавить ноль к $number
, Если ответ 0
тогда попробуй expr
чтобы проверить это $number
не ноль
Поскольку в последнее время мне приходилось вмешиваться в это, и мне больше всего нравился подход Картту с модульным тестом. Я пересмотрел код и добавил некоторые другие решения, попробуйте сами, чтобы увидеть результаты:
#!/bin/bash
# N={0,1,2,3,...} by syntaxerror
function isNaturalNumber()
{
[[ ${1} =~ ^[0-9]+$ ]]
}
# Z={...,-2,-1,0,1,2,...} by karttu
function isInteger()
{
[[ ${1} == ?(-)+([0-9]) ]]
}
# Q={...,-½,-¼,0.0,¼,½,...} by karttu
function isFloat()
{
[[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
# R={...,-1,-½,-¼,0.E+n,¼,½,1,...}
function isNumber()
{
isNaturalNumber $1 || isInteger $1 || isFloat $1
}
bools=("TRUE" "FALSE")
int_values="0 123 -0 -123"
float_values="0.0 0. .0 -0.0 -0. -.0 \
123.456 123. .456 -123.456 -123. -.456 \
123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
false_values="blah meh mooh blah5 67mooh a123bc"
for value in ${int_values} ${float_values} ${false_values}
do
printf " %5s=%-30s" $(isNaturalNumber $value) ${bools[$?]} $(printf "isNaturalNumber(%s)" $value)
printf "%5s=%-24s" $(isInteger $value) ${bools[$?]} $(printf "isInteger(%s)" $value)
printf "%5s=%-24s" $(isFloat $value) ${bools[$?]} $(printf "isFloat(%s)" $value)
printf "%5s=%-24s\n" $(isNumber $value) ${bools[$?]} $(printf "isNumber(%s)" $value)
done
Таким образом, isNumber() включает в себя тире, запятые и экспоненциальную запись, и поэтому возвращает TRUE для целых чисел и чисел с плавающей запятой, тогда как isFloat() возвращает FALSE для целочисленных значений, а isInteger() также возвращает FALSE для чисел с плавающей запятой. Для вашего удобства все как один лайнер:
isNaturalNumber() { [[ ${1} =~ ^[0-9]+$ ]]; }
isInteger() { [[ ${1} == ?(-)+([0-9]) ]]; }
isFloat() { [[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]; }
isNumber() { isNaturalNumber $1 || isInteger $1 || isFloat $1; }
Я использую printf в качестве других упомянутых ответов, если вы предоставите строку формата "%f" или "%i", printf выполнит проверку за вас. Синтаксис проще, чем изобретать чеки, и он короток, а printf вездесущ. Так что, на мой взгляд, это достойный выбор - вы также можете использовать следующую идею для проверки ряда вещей, она полезна не только для проверки чисел.
declare -r CHECK_FLOAT="%f"
declare -r CHECK_INTEGER="%i"
## <arg 1> Number - Number to check
## <arg 2> String - Number type to check
## <arg 3> String - Error message
function check_number() {
local NUMBER="${1}"
local NUMBER_TYPE="${2}"
local ERROR_MESG="${3}"
local -i PASS=1
local -i FAIL=0
case "${NUMBER_TYPE}" in
"${CHECK_FLOAT}")
if ((! $(printf "${CHECK_FLOAT}" "${NUMBER}" &>/dev/random;echo $?))); then
echo "${PASS}"
else
echo "${ERROR_MESG}" 1>&2
echo "${FAIL}"
fi
;;
"${CHECK_INTEGER}")
if ((! $(printf "${CHECK_INTEGER}" "${NUMBER}" &>/dev/random;echo $?))); then
echo "${PASS}"
else
echo "${ERROR_MESG}" 1>&2
echo "${FAIL}"
fi
;;
*)
echo "Invalid number type format: ${NUMBER_TYPE} to check_number()." 1>&2
echo "${FAIL}"
;;
esac
}
>$ var=45
>$ (($(check_number $var "${CHECK_INTEGER}" "Error: Found $var - An integer is required."))) && { echo "$var+5" | bc; }
Мне нравится ответ Альберто Закканьи.
if [ "$var" -eq "$var" ] 2>/dev/null; then
Важные предварительные условия: - не создаются подоболочки - не запускаются парсеры RE - большинство приложений оболочки не используют реальные числа
Но если $var
является сложным (например, доступ к ассоциативному массиву), и если число будет неотрицательным целым числом (в большинстве случаев), то, возможно, это более эффективно?
if [ "$var" -ge 0 ] 2> /dev/null; then ..
Чтобы поймать отрицательные числа:
if [[ $1 == ?(-)+([0-9.]) ]]
then
echo number
else
echo not a number
fi
Вы можете использовать "let" тоже так:
[ ~]$ var=1
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=01
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=toto
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s not a number
[ ~]$
Но я предпочитаю использовать оператор "=~" Bash 3+, как некоторые ответы в этой теме.
Синтаксис почти такой, как вы хотите. Просто нужна функция
isnumber
:
#!/usr/bin/bash
isnumber(){
num=$1
if [ -z "${num##*[!0-9]*}" ];
then return 1
else
return 0
fi
}
$(isnumber $1) && VAR=$1 || echo "need a number";
echo "VAR is $VAR"
контрольная работа:
$ ./isnumtest 10
VAR is 10
$ ./isnumtest abc10
need a number
VAR is
переменная для проверки
number=12345
или жеnumber=-23234
или жеnumber=23.167
или жеnumber=-345.234
проверить числовой или не числовой
echo $number | grep -E '^-?[0-9]*\.?[0-9]*$' > /dev/null
принять решение о дальнейших действиях на основе статуса выхода из вышеупомянутого
if [ $? -eq 0 ]; then echo "Numeric"; else echo "Non-Numeric"; fi
printf '%b' "-123\nABC" | tr '[:space:]' '_' | grep -q '^-\?[[:digit:]]\+$' && echo "Integer." || echo "NOT integer."
Удалить -\?
в шаблоне соответствия grep, если вы не принимаете отрицательное целое число.
Easy-to-understand and compatible solution, with
test
command :
test $myVariable -eq 0 2>/dev/null
if [ $? -le 1 ]; then echo 'ok'; else echo 'KO'; fi
If myVariable = 0, the return code is 0
If myVariable > 0, the return code is 1
If myVariable is not an integer, the return code is 2
Я использую следующее (для целых чисел):
## ##### constants
##
## __TRUE - true (0)
## __FALSE - false (1)
##
typeset -r __TRUE=0
typeset -r __FALSE=1
## --------------------------------------
## isNumber
## check if a value is an integer
## usage: isNumber testValue
## returns: ${__TRUE} - testValue is a number else not
##
function isNumber {
typeset TESTVAR="$(echo "$1" | sed 's/[0-9]*//g' )"
[ "${TESTVAR}"x = ""x ] && return ${__TRUE} || return ${__FALSE}
}
isNumber $1
if [ $? -eq ${__TRUE} ] ; then
print "is a number"
fi