คำตอบที่ชัดเจนได้รับจาก @charles Dufy และคนอื่น ๆ แล้ว วิธีทุบตีบริสุทธิ์จะใช้สิ่งต่อไปนี้:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+[.,]?[0-9]*$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
แม้ว่าสำหรับจำนวนจริงมันไม่จำเป็นต้องมีตัวเลขก่อนจุดฐานจุดฐาน
เพื่อให้การสนับสนุนอย่างละเอียดยิ่งขึ้นของตัวเลขลอยตัวและสัญกรณ์ทางวิทยาศาสตร์ (หลายโปรแกรมใน C / Fortran หรืออื่น ๆ จะส่งออกลอยตัวด้วยวิธีนี้) การเพิ่มประโยชน์ให้กับบรรทัดนี้จะเป็นดังต่อไปนี้:
string="1.2345E-67"
if [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]?-?[0-9]+$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
จึงนำไปสู่การแยกประเภทของตัวเลขหากคุณกำลังมองหาประเภทเฉพาะ:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+$ ]]
then
echo $string is an integer
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*$ ]]
then
echo $string is a float
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]-?[0-9]+$ ]]
then
echo $string is a scientific number
else
echo $string is not a number
fi
หมายเหตุ: เราสามารถแสดงรายการข้อกำหนดเกี่ยวกับการสร้างประโยคสำหรับสัญกรณ์ทศนิยมและวิทยาศาสตร์หนึ่งรายการเพื่ออนุญาตให้ใช้เครื่องหมายจุลภาคเป็นจุดฐานเช่นเดียวกับ "." จากนั้นเราจะยืนยันว่าจะต้องมีจุด Radix เพียงจุดเดียวเท่านั้น สามารถมีเครื่องหมาย +/- สองอันในทุ่น [Ee] ฉันได้เรียนรู้กฎเพิ่มเติมจากการทำงานของ Aulu และทดสอบกับสตริงที่ไม่ดีเช่น '' '-' '-E-1' '0-0' นี่คือเครื่องมือ regex / substring / expr ของฉันที่ดูเหมือนจะค้าง:
parse_num() {
local r=`expr "$1" : '.*\([.,]\)' 2>/dev/null | tr -d '\n'`
nat='^[+-]?[0-9]+[.,]?$' \
dot="${1%[.,]*}${r}${1##*[.,]}" \
float='^[\+\-]?([.,0-9]+[Ee]?[-+]?|)[0-9]+$'
[[ "$1" == $dot ]] && [[ "$1" =~ $float ]] || [[ "$1" =~ $nat ]]
} # usage: parse_num -123.456
test && echo "foo" && exit 0 || echo "bar" && exit 1
วิธีการที่คุณใช้อาจมีผลข้างเคียงบางอย่างที่ไม่ได้ตั้งใจ - ถ้าสะท้อนล้มเหลว (อาจจะส่งออกคือการปิด FD) ที่จะถูกข้ามไปและรหัสแล้วจะพยายามที่จะexit 0
echo "bar"
ถ้ามันล้มเหลวเช่นกัน&&
สภาพก็จะล้มเหลวและมันก็จะไม่ทำงานexit 1
! การใช้if
ข้อความจริงมากกว่า&&
/||
มีแนวโน้มน้อยที่จะเกิดผลข้างเคียงที่ไม่คาดคิด