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ą?

Odpowiedzi:


25

Usuń cytaty

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


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.

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

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

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.


OPTINDtu też jest dobrze. tylko saiyan.
mikeserv

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.