Verifica se un numero di input è un numero intero


31

Sto cercando di verificare se un input è un numero intero e ci ho provato centinaia di volte ma non vedo l'errore in questo. Purtroppo non funziona, attiva l'istruzione if per tutti gli input (numeri / lettere)

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

Ho giocato con le virgolette ma o l'ho mancato o non ha fatto nulla. Cosa faccio di sbagliato? Esiste un modo più semplice per verificare se un input è solo un INTEGER?

Risposte:


25

Rimuovi virgolette

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

stackoverflow.com/questions/806906/… aveva le virgolette all'indietro
lonewarrior556

Quindi c'è un bug. Con le virgolette il regexp viene trattato come una stringa letterale. Si può verificare conscale='^[0-9]+$'; [[ "$scale" == "^[0-9]+$" ]] && echo equal || echo "not equal"
jimmij il

15

Usa l' -eqoperatore del comando test :

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

Funziona non solo con bashqualsiasi shell POSIX. Dalla documentazione del test POSIX :

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

che controlla se è un numero qualsiasi, non solo numeri interi
lonewarrior556

2
@ lonewarrior556: funziona solo per numeri interi, vedi: pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html . Immagino tu abbia detto per qualsiasi numero perché usi un nuovo test [[invece del vecchio test [come il mio.
cuonglm,

Buona idea ma un po 'rumorosa. Preferirei non dover reindirizzare gli errori a dev null.
Carattere jolly

2
@Wildcard: Sì, paghiamo per la portabilità.
cuonglm,

8

Per numeri interi senza segno uso:

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

test:

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

Sorry integers only

1
Mi piace quello in quanto è realizzato con builtin, veloce e sembra abbastanza posix ... Ho provato su una vecchia shell (bash 2.0.5) e funziona perfettamente.
Olivier Dulac il

Che dire degli spazi all'interno dell'argomento? Come "086" .
0andriy,

@ 0andriy Vedi il secondo test.
raciasolvo,

8

Poiché l'OP sembra voler solo numeri interi positivi:

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

Esempi:

$ 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

Si noti che [è richiesto un singolo 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

Questo perché la dereferenziazione si verifica con [[:

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

questa è la vera risposta ... altri falliti
Scott Stensland,

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

Questo fa il controllo e genera l'errore.


OPTINDva bene anche qui. solo Saiyan.
Mikeserv,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.