Memeriksa apakah nomor input bilangan bulat

31

Saya mencoba memeriksa apakah input bilangan bulat dan saya sudah membahasnya seratus kali tetapi tidak melihat kesalahan dalam hal ini. Sayangnya itu tidak berfungsi, itu memicu pernyataan if untuk semua input (angka / huruf)

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

Saya telah bermain-main dengan tanda kutip tetapi entah melewatkannya atau tidak melakukan apa pun. Apa yang saya lakukan salah? Apakah ada cara yang lebih mudah untuk menguji apakah input hanyalah sebuah INTEGER?

lonewarrior556
sumber

Jawaban:

25

Hapus kutipan

if ! [[ "$scale" =~ ^[0-9]+$ ]]
    then
        echo "Sorry integers only"
fi
jimmij
sumber
stackoverflow.com/questions/806906/… memiliki tanda kutip mundur
lonewarrior556
Jadi ada bug. Dengan kutipan, regexp diperlakukan sebagai string literal. Orang dapat memeriksanya denganscale='^[0-9]+$'; [[ "$scale" == "^[0-9]+$" ]] && echo equal || echo "not equal"
jimmij
15

Gunakan -eqoperator perintah uji :

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

Ini tidak hanya berfungsi bashtetapi juga shell POSIX. Dari dokumentasi tes POSIX :

n1 -eq  n2
    True if the integers n1 and n2 are algebraically equal; otherwise, false.
cuonglm
sumber
yang memeriksa apakah nomornya ada, bukan hanya bilangan bulat
lonewarrior556
2
@ lonewarrior556: Ini hanya berfungsi untuk integer, lihat: pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html . Saya kira Anda mengatakan angka apa pun karena Anda menggunakan tes baru [[alih-alih tes lama [sebagai milik saya.
cuonglm
Ide bagus tapi agak berisik. Saya lebih suka tidak perlu mengarahkan kesalahan ke dev null.
Wildcard
2
@ Kartu Memori: Ya, kami membayarnya untuk portabilitas.
cuonglm
8

Untuk bilangan bulat yang tidak ditandatangani, saya menggunakan:

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

Tes:

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

Sorry integers only
raciasolvo
sumber
1
Saya suka yang itu karena dibuat dengan builtin, cepat, dan tampaknya cukup posix ... Saya mencoba shell yang lama (bash 2.0.5) dan bekerja dengan sempurna.
Olivier Dulac
Bagaimana dengan spasi di dalam argumen? Seperti "086" .
0andriy
@ 0 danriy Lihat tes kedua.
raciasolvo
8

Karena OP tampaknya hanya menginginkan bilangan bulat positif:

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

Contoh:

$ 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

Perhatikan bahwa satu [tes diperlukan:

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

Ini karena dereferencing terjadi dengan [[:

$ word=other
$ other=3                                                                                                                                                                                  
$ [[ $word -eq 3 ]] && echo word equals other equals 3
word equals other equals 3
Tom Hale
sumber
inilah jawaban sebenarnya ... yang lain gagal
Scott Stensland
3
( scale=${scale##*[!0-9]*}
: ${scale:?input must be an integer}
) || exit

Itu memeriksa dan menampilkan kesalahan Anda.

mikeserv
sumber
OPTINDjuga bagus di sini. hanya syan
mikeserv