Prüfen, ob eine eingegebene Nummer eine Ganzzahl ist

31

Ich versuche zu überprüfen, ob es sich bei einer Eingabe um eine Ganzzahl handelt, und ich habe sie hundert Mal durchgesehen, sehe aber den Fehler darin nicht. Leider funktioniert es nicht, es löst die if-Anweisung für alle Eingaben (Zahlen / Buchstaben) aus

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

Ich habe mit den Zitaten herumgespielt, sie aber entweder verpasst oder sie haben nichts bewirkt. Was mache ich falsch? Gibt es eine einfachere Möglichkeit zu testen, ob eine Eingabe nur ein INTEGER ist?

lonewarrior556
quelle

Antworten:

25

Entfernen Sie Anführungszeichen

if ! [[ "$scale" =~ ^[0-9]+$ ]]
    then
        echo "Sorry integers only"
fi
jimmij
quelle
stackoverflow.com/questions/806906/… hatte die Anführungszeichen rückwärts
lonewarrior556
Es gibt also einen Bug. Bei Anführungszeichen wird der reguläre Ausdruck als wörtliche Zeichenfolge behandelt. Das kann man mitscale='^[0-9]+$'; [[ "$scale" == "^[0-9]+$" ]] && echo equal || echo "not equal"
jimmij 22.08.14
15

Verwenden Sie den -eqOperator des Testbefehls :

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

Es funktioniert nicht nur in bashjeder POSIX-Shell, sondern auch in jeder anderen. Aus der POSIX- Testdokumentation :

n1 -eq  n2
    True if the integers n1 and n2 are algebraically equal; otherwise, false.
cuonglm
quelle
das prüft, ob es eine beliebige Zahl ist, nicht nur ganze Zahlen
lonewarrior556
2
@ lonewarrior556: Es funktioniert nur für Ganzzahlen, siehe: pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html . Ich denke, Sie haben für eine beliebige Anzahl gesagt, weil Sie als meinen neuen Test [[anstelle des alten Tests verwenden [.
Donnerstag,
Gute Idee, aber etwas laut. Ich würde Fehler lieber nicht zu dev null umleiten müssen.
Wildcard
2
@Wildcard: Ja, wir bezahlen es für die Portabilität.
Cuonglm
8

Für vorzeichenlose ganze Zahlen verwende ich:

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

Tests:

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

Sorry integers only
raciasolvo
quelle
1
Ich mag diese, da sie mit eingebauten Funktionen erstellt wurde, schnell ist und ziemlich gut aussieht ... Ich habe eine alte Shell (Bash 2.0.5) ausprobiert und sie funktioniert einwandfrei.
Olivier Dulac
Was ist mit Leerzeichen innerhalb des Arguments? Wie "086" .
0andriy
@ 0andriy Siehe den zweiten Test.
raciasolvo
8

Da die OP nur positive ganze Zahlen zu wollen scheint:

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

Beispiele:

$ 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

Beachten Sie, dass ein einzelner [Test erforderlich ist:

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

Dies liegt daran, dass die Dereferenzierung mit [[folgenden Elementen erfolgt :

$ word=other
$ other=3                                                                                                                                                                                  
$ [[ $word -eq 3 ]] && echo word equals other equals 3
word equals other equals 3
Tom Hale
quelle
Dies ist die wahre Antwort ... andere scheiterten
Scott Stensland
3
( scale=${scale##*[!0-9]*}
: ${scale:?input must be an integer}
) || exit

Das prüft und gibt Ihren Fehler aus.

mikeserv
quelle
OPTINDist auch hier gut. nur saiyan.
mikeserv
2

Bitte überprüfen Sie, wie ich teste, ob eine Variable eine Zahl auf der Bash- Stackoverflow-Seite ist. Auf dieser Seite finden Sie weitere gute Möglichkeiten, um die Ganzzahl zu überprüfen.

Reza Harasani
quelle