พยายามหาวิธีแปลงอาร์กิวเมนต์เป็นจำนวนเต็มเพื่อดำเนินการทางคณิตศาสตร์แล้วพิมพ์ออกมาพูดเพื่อaddOne.sh
:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
พยายามหาวิธีแปลงอาร์กิวเมนต์เป็นจำนวนเต็มเพื่อดำเนินการทางคณิตศาสตร์แล้วพิมพ์ออกมาพูดเพื่อaddOne.sh
:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
คำตอบ:
ใน bash ไม่มีใคร "แปลงอาร์กิวเมนต์เป็นจำนวนเต็มเพื่อดำเนินการทางคณิตศาสตร์" ใน bash ตัวแปรจะถือว่าเป็นจำนวนเต็มหรือสตริงขึ้นอยู่กับบริบท
$((...))
ในการดำเนินการทางคณิตศาสตร์ที่คุณควรจะเรียกผู้ประกอบการขยายตัวทางคณิตศาสตร์ ตัวอย่างเช่น:
$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3
หรือที่ต้องการโดยทั่วไป:
$ echo "$((a + 1))"
3
คุณควรระวังว่า bash (ตรงข้ามกับ ksh93, zsh หรือ yash) ทำการคำนวณทางเลขจำนวนเต็มเท่านั้น หากคุณมีตัวเลขจุดลอยตัว (ตัวเลขที่มีทศนิยม) แสดงว่ามีเครื่องมืออื่น ๆ ที่จะช่วยเหลือ ตัวอย่างเช่นใช้bc
:
$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14
หรือคุณสามารถใช้เชลล์ที่มีการสนับสนุนเลขคณิตของทศนิยมแทนการทุบตี:
zsh> echo $((3.14 + 1))
4.14
วิธีอื่นคุณสามารถใช้ expr
Ex:
$ version="0002"
$ expr $version + 0
2
$ expr $version + 1
3
ในbash
คุณสามารถทำการแปลงจากอะไรก็ได้เป็นจำนวนเต็มโดยใช้printf -v :
printf -v int '%d\n' "$1" 2>/dev/null
จำนวนลอยตัวจะถูกแปลงเป็นจำนวนเต็มในขณะที่สิ่งใดที่ดูเหมือนว่าตัวเลขจะถูกแปลงเป็น 0 การยกกำลังจะถูกปัดเศษเป็นจำนวนก่อน e
ตัวอย่าง:
$ printf -v int '%d\n' 123.123 2>/dev/null
$ printf '%d\n' "$int"
123
$ printf -v int '%d\n' abc 2>/dev/null
$ printf '%d\n' "$int"
0
$ printf -v int '%d\n' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1
printf -v
สิ่งนี้สามารถทำได้ด้วยการทดแทนคำสั่ง:int="$(printf '%d' 123.123 2>/dev/null)"
bash
คุณใช้เวอร์ชั่นอะไร
สถานการณ์ที่คล้ายกันเกิดขึ้นเมื่อเร็ว ๆ นี้เมื่อพัฒนาสคริปต์ทุบตีเพื่อให้ทำงานได้ทั้งในสภาพแวดล้อม Linux และ OSX ผลลัพธ์ของคำสั่งเดียวใน OSX จะส่งคืนสตริงที่มีรหัสผลลัพธ์ เช่น" 0"
. แน่นอนสิ่งนี้ไม่สามารถทดสอบได้อย่างถูกต้องในกรณีต่อไปนี้:
if [[ $targetCnt != 0 ]]; then...
วิธีแก้ปัญหาคือการบังคับ (เช่น 'แปลง') ผลลัพธ์เป็นจำนวนเต็มคล้ายกับสิ่งที่ @ John1024 ตอบไว้ข้างต้นเพื่อให้ทำงานได้ตามที่คาดไว้:
targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...
==
etc in [[
( [
หรือ aka test
) ทำการเปรียบเทียบสตริง มีโอเปอเรเตอร์ต่าง ๆสำหรับการเปรียบเทียบทางคณิตศาสตร์เช่น[[ $targetcnt -ne 0 ]]
; ดู manpage (หรือข้อมูล) ภายใต้นิพจน์เงื่อนไข เพื่อตัดช่องว่างโดยเฉพาะคุณสามารถใช้[
กับการขยายตัวตัวแปร[ $targetcnt == 0 ]
ที่ไม่ได้ระบุไว้เพื่อรับ wordplitting เริ่มต้น (ไม่ได้ทำใน[[
) แต่โดยทั่วไปวิธีการที่จะนำคุณไปสู่อันตราย
ใส่ใจเกี่ยวกับรหัสสีแม้ในการติดตาม ( -x
) พวกเขาจะไม่ปรากฏสิ่งที่จะให้มันออกมาก็คือสตริงที่ควรจะเป็นตัวเลขที่ถูกห่อด้วยคำพูดไม่ว่าคุณจะพิมพ์มัน
$((var+var))
ล้มเหลว แม้ว่าคุณecho
หรือprintf
ทั้งสองจะแตกต่างกัน ฉันไม่ทราบวิธีแก้ไขเนื่องจากฉันสามารถแก้ไขได้โดยการปิดการใช้งานรหัสสีที่แหล่งที่มาของผลลัพธ์ ในการสังเกตเห็นในบันทึกการติดตามคุณจะเห็นตัวแปรที่ได้รับมอบหมายเช่นเดียวกับvar='0'
ที่ควรจะเป็นvar=0
sed
หากคุณไม่สามารถปิดการใช้งานได้
printf "1 + %s\n" $1 won't do ?