Sprawdzanie, czy liczba wejściowa jest liczbą całkowitą

31

Próbuję sprawdzić, czy dane wejściowe są liczbami całkowitymi i przekroczyłem je sto razy, ale nie widzę w tym błędu. Niestety nie działa, uruchamia instrukcję if dla wszystkich danych wejściowych (cyfr / liter)

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

Bawiłem się cytatami, ale albo to przegapiłem, albo nic nie zrobiłem. Co robię źle? Czy istnieje łatwiejszy sposób sprawdzenia, czy wejście jest tylko liczbą całkowitą?

lonewarrior556
źródło

Odpowiedzi:

25

Usuń cytaty

if ! [[ "$scale" =~ ^[0-9]+$ ]]
    then
        echo "Sorry integers only"
fi
jimmij
źródło
stackoverflow.com/questions/806906/... miał cytaty wstecz
lonewarrior556
Więc jest błąd. W cudzysłowach wyrażenie regularne jest traktowane jako ciąg literalny. Można to sprawdzić za pomocąscale='^[0-9]+$'; [[ "$scale" == "^[0-9]+$" ]] && echo equal || echo "not equal"
jimmij
15

Użyj -eqoperatora polecenia testowego :

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

Działa nie tylko w bashdowolnej powłoce POSIX. Z dokumentacji testu POSIX :

n1 -eq  n2
    True if the integers n1 and n2 are algebraically equal; otherwise, false.
Cuonglm
źródło
sprawdza, czy jest to jakakolwiek liczba, nie tylko liczby całkowite
lonewarrior556
2
@ lonewarrior556: Działa tylko dla liczb całkowitych, patrz: pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html . Myślę, że powiedziałeś dla dowolnej liczby, ponieważ używasz nowego testu [[zamiast starego testu [jako mojego.
cuonglm
Dobry pomysł, ale trochę głośny. Wolałbym nie przekierowywać błędów do dev null.
Wildcard
2
@Wildcard: Tak, płacimy za przenośność.
cuonglm
8

W przypadku liczb całkowitych bez znaku używam:

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

Testy:

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

Sorry integers only
raciasolvo
źródło
1
Podoba mi się ten, ponieważ ma wbudowane, szybkie i wydaje się dość posiksowy ... Próbowałem na starej powłoce (bash 2.0.5) i działa idealnie.
Olivier Dulac,
Co ze spacjami wewnątrz argumentu? Jak „086” .
0andriy
@ 0andriy Zobacz drugi test.
raciasolvo
8

Ponieważ PO wydaje się chcieć tylko dodatnich liczb całkowitych:

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

Przykłady:

$ 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

Pamiętaj, że [wymagany jest pojedynczy test:

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

Wynika to z faktu, że dereferencje występują z [[:

$ word=other
$ other=3                                                                                                                                                                                  
$ [[ $word -eq 3 ]] && echo word equals other equals 3
word equals other equals 3
Tom Hale
źródło
to jest prawdziwa odpowiedź ... inni zawiedli
Scott Stensland
3
( scale=${scale##*[!0-9]*}
: ${scale:?input must be an integer}
) || exit

Sprawdza to i wyświetla błąd.

mikeserv
źródło
OPTINDtu też jest dobrze. tylko saiyan.
mikeserv