Перевірка, чи вхідне число є цілим числом


31

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

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

Я грав з цитатами, але або пропустив це, або нічого не зробив. Що я роблю неправильно? Чи є простіший спосіб перевірити, чи вхід є лише ІНТЕГЕР?

Відповіді:


25

Видаліть цитати

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


Так що виникає помилка. З цитатами, регулярне вираження розглядається як буквальний рядок. Можна перевірити це за допомогою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
Мені подобається той, як він зроблений з вбудованими, швидкими і, здається, досить позитивними ... Я приміряв стару оболонку (bash 2.0.5), і вона працює чудово.
Олів’є Дулак

Що з пробілами всередині аргументу? Як і "086" .
0андрій

@ 0andriy Дивіться другий тест.
raciasolvo

8

Оскільки ОП, схоже, хоче лише додатних цілих чисел:

[ "$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.