Проверка, является ли входной номер целым числом


31

Я пытаюсь проверить, является ли ввод целым числом, и я прошел через него сто раз, но не вижу ошибки в этом. Увы, он не работает, он запускает оператор if для всех входных данных (цифры / буквы)

read scale
if ! [[ "$scale" =~ "^[0-9]+$" ]]
        then
            echo "Sorry integers only"
fi

Я играл с цитатами, но либо пропустил, либо ничего не сделал. Что я делаю не так? Есть ли более простой способ проверить, является ли вход просто INTEGER?

Ответы:


25

Удалить цитаты

if ! [[ "$scale" =~ ^[0-9]+$ ]]
    then
        echo "Sorry integers only"
fi

stackoverflow.com/questions/806906/… имел кавычки задом наперед
lonewarrior556

Так что есть ошибка. С кавычками регулярное выражение обрабатывается как буквенная строка. Это можно проверить с помощьюscale='^[0-9]+$'; [[ "$scale" == "^[0-9]+$" ]] && echo equal || echo "not equal"
jimmij

15

Используйте -eqоператор тестовой команды:

read scale
if ! [ "$scale" -eq "$scale" ] 2> /dev/null
then
    echo "Sorry integers only"
fi

Он работает не только в bashлюбой оболочке POSIX, но и в ней. Из тестовой документации POSIX :

n1 -eq  n2
    True if the integers n1 and n2 are algebraically equal; otherwise, false.

который проверяет, есть ли какое-нибудь число, а не только целые числа
lonewarrior556

2
@ lonewarrior556: работает только для целых чисел, см .: pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html . Я думаю, вы сказали для любого числа, потому что вы используете новый тест [[вместо старого теста, [как мой.
cuonglm

Хорошая идея, но немного шумно. Я бы предпочел не перенаправлять ошибки на dev null.
Wildcard

2
@Wildcard: Да, мы платим за мобильность.
Cuonglm

8

Для целых чисел без знака я использую:

read -r scale
[ -z "${scale//[0-9]}" ] && [ -n "$scale" ] || echo "Sorry integers only"

Испытания:

$ ./test.sh
7
$ ./test.sh
   777
$ ./test.sh
a
Sorry integers only
$ ./test.sh
""
Sorry integers only
$ ./test.sh

Sorry integers only

1
Мне нравится этот, так как он сделан со встроенными, быстрыми, и, кажется, довольно posix ... Я попробовал на старой оболочке (Bash 2.0.5), и она отлично работает.
Оливье Дюлак

Как насчет пробелов внутри аргумента? Как «086» .
0andriy

@ 0andriy Смотрите второй тест.
raciasolvo

8

Поскольку OP, кажется, хочет только положительные целые числа:

[ "$1" -ge 0 ] 2>/dev/null

Примеры:

$ is_positive_int(){ [ "$1" -ge 0 ] 2>/dev/null && echo YES || echo no; }
$ is_positive_int word
no
$ is_positive_int 2.1
no
$ is_positive_int -3
no
$ is_positive_int 42
YES

Обратите внимание, что требуется один [тест:

$ [[ "word" -eq 0 ]] && echo word equals zero || echo nope
word equals zero
$ [ "word" -eq 0 ] && echo word equals zero || echo nope
-bash: [: word: integer expression expected
nope

Это потому, что разыменование происходит с [[:

$ word=other
$ other=3                                                                                                                                                                                  
$ [[ $word -eq 3 ]] && echo word equals other equals 3
word equals other equals 3

это реальный ответ ... другие не смогли
Скотт Стенсланд

3
( scale=${scale##*[!0-9]*}
: ${scale:?input must be an integer}
) || exit

Это делает проверку и выводит вашу ошибку.


OPTINDЗдесь тоже хорошо. просто Сайян.
mikeserv

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.