ฉันจะเพิ่ม (ลบ ฯลฯ ) สองตัวเลขด้วย bash ได้อย่างไร


90

ฉันสามารถอ่านตัวเลขและการดำเนินการด้วย:

echo "First number please"
read num1
echo "Second number please"
read num2
echo "Operation?"
read op

แต่ความพยายามของฉันทั้งหมดเพื่อเพิ่มหมายเลขล้มเหลว:

case "$op" in
  "+")
    echo num1+num2;;
  "-")
    echo `num1-num2`;;
esac

วิ่ง:

First number please
1
Second mumber please
2
Operation?
+

เอาท์พุท:

num1+num2

...หรือ...

echo $num1+$num2;;

# results in: 1+2    

...หรือ...

echo `$num1`+`$num2`;;

# results in: ...line 9: 1: command not found

ดูเหมือนว่าฉันยังคงได้รับสตริงบางทีเมื่อฉันลองเพิ่มเพิ่ม ("2 + 2" แทนที่จะเป็น "4")


5
ฉันแก้ไขชื่อของคุณเพราะที่นี่เป็นคำถามที่ดีทั่วไปและถ้าคุณลดลงบริบทลงที่คุณจะได้ตระหนักในเรื่องนี้มีอะไรจะทำอย่างไรกับcaseหรืออะไรยกเว้นหนึ่งบรรทัด: echo $num+$numตั้งแต่ที่จะทำให้เกิดปัญหาว่า แนวคิดที่มีการย่อขนาดบริบทในคำถามการเขียนโปรแกรมมีอธิบายไว้ที่นี่: sscce.org
goldilocks

2
+1 สวัสดี goldilocks ใช่ว่าเห็นได้ชัดสำหรับฉันในภายหลัง แต่ใช่ฉันเห็นด้วยกับการให้เหตุผลของคุณทั้งหมดและใช่ยิ่งคำถามและ 'เอกพจน์' ดีขึ้นเท่านั้น ฉันยินดีรับการแก้ไข :) ขอบคุณคุณ :)
Michael Durrant

คำตอบ:


116

การคำนวณทางคณิตศาสตร์ในเชลล์ POSIXเสร็จสิ้นด้วย$และวงเล็บคู่(( )):

echo "$(($num1+$num2))"

คุณสามารถกำหนดจาก (sans echo):

num1="$(($num1+$num2))"

นอกจากนี้ยังมีexpr:

expr $num1 + $num2

ในการเขียนสคริปต์$(())จะดีกว่าเพราะมันหลีกเลี่ยงทางแยก / รันสำหรับexprคำสั่ง


หรือแม้กระทั่งโดยตรงโดยไม่เกี่ยวข้องกับecho $(($num1$op$num2)) case
จัดการ

ไม่มีcaseส่วนเกี่ยวข้องที่นี่
goldilocks

1
ไม่ แต่คุณใช้ตัวอักษร+ดังนั้นจะต้องใช้caseด้านนอกเพื่อจัดการการลบแยกต่างหาก
จัดการ

1
@ การจัดการงาน: คุณหมายถึงกำจัดสิ่งที่caseอยู่ในรหัสของ OP ด้วยecho $(($num1$op$num2))- ซึ่งจะใช้งานได้ แต่การใช้งานcaseนั้นแข็งแกร่งกว่าเนื่องจากคุณสามารถจัดการข้อผิดพลาดด้วยค่าเริ่มต้น*ได้
goldilocks

+1 ให้กับคุณทั้งคู่ ฉันใช้เคส (อาจไม่ได้แสดงตอนเริ่มต้น) แต่เมื่อคุณทั้งสองรู้ว่าปัญหาไม่ได้เกี่ยวกับเคส
Michael Durrant

13

คำตอบที่มีอยู่คือทุบตีบริสุทธิ์ดังนั้นมันจะเร็วกว่านี้ แต่สามารถจัดการได้เฉพาะจำนวนเต็ม bcหากคุณต้องการที่จะจัดการกับลอยที่คุณต้องใช้โปรแกรมภายนอก

$ echo 'scale=4;3.1415+9.99' | bc
13.1315

การscale=4บอกbcให้ใช้ทศนิยมสี่ตำแหน่ง ดูman bcข้อมูลเพิ่มเติม


หมายเหตุ: ในขณะที่bashไม่สนับสนุนเลขคณิตจุดลอยกับ$((...))เปลือกหอยจำนวนมาก ( ksh93, zsh, yashอย่างน้อย) ทำ ข้อได้เปรียบของbcมันคือมันรองรับความแม่นยำโดยพลการในขณะที่เชลล์ arithmetics จำกัดdoubleประเภทของโปรเซสเซอร์ โปรดทราบว่าคุณไม่จำเป็นต้องตั้งค่าscaleที่นี่ สำหรับการเพิ่มเติมscaleพารามิเตอร์จะไม่ถูกใช้ ขนาดของ3.1415+9.99จะมาจากตัวถูกดำเนินการ (ที่นี่ 4)
Stéphane Chazelas

จะทำคณิตศาสตร์ได้อย่างไรถ้ามีค่าหนึ่ง450และอีกหนึ่งเป็นทศนิยมที่เก็บอยู่ในตัวแปร$mynumber? ตัวอย่างเช่น450-$mynumber.
Sigur

@ ร่างecho "450-$mynumber" | bcควรทำมัน หากคุณต้องการให้ตัวแปรขยายคุณต้องใช้เครื่องหมายคำพูดคู่แทนคำพูดเดี่ยว
evilsoup

@evilsoup ตอนนี้มันทำงานเหมือนมีเสน่ห์ ขอบคุณ
Sigur

computedval=$(echo 'scale=10;var1-var2' | bc)ไม่ทำงานไม่ทำงานcomputedval=$(echo 'scale=10;$var1-$var2' | bc)
StatsSorceress

5
echo `expr $a + $b`   
echo `expr $a - $b`   
echo `expr $a \* $b`   
echo `expr $a / $b`   

หมายเหตุ\ก่อนหน้า*(สำหรับการคูณ) นิพจน์ทั้งหมดจะต้องอยู่ภายใน backquotes `


1
exprไม่จำเป็นและไม่จำเป็นต้องบันทึกเอาต์พุตมาตรฐานของคำสั่งเพียงเพื่อเขียนกลับไปยังเอาต์พุตมาตรฐาน
chepner


1

คุณยังสามารถใช้$[ ... ]โครงสร้าง ในกรณีนี้เราใช้ mechanizm ในตัวใน Bash ซึ่งเร็วกว่าและใช้สะดวกกว่าเล็กน้อย เนื่องจากเรารู้ทุกอย่างระหว่าง $ ที่ [และ] $จะถือว่าเป็นการแสดงออกของเราไม่จำเป็นต้องนำหน้าตัวแปรที่มี ในทำนองเดียวกันเราไม่จำเป็นต้องปลอดภัย*จากการปฏิบัติเหมือนรูปแบบ

num1=2
num2=3
echo $[num1 + num2]
5

0

จากลำดับของอินพุตที่คุณร้องขอจากผู้ใช้ดูเหมือนว่าคุณกำลังใช้สัญลักษณ์ขัดเงาย้อนกลับ

echo "First number please"
read num1
echo "Second number please"
read num2
echo "Operation?"
read op

คุณอาจทำได้ดีกว่าเพียงใช้dc(เครื่องคิดเลขแบบตั้งโต๊ะ) โดยตรงเนื่องจากเป็นแบบนั้น

DESCRIPTION
       Dc is a reverse-polish desk calculator which supports unlimited pre-
       cision arithmetic.

ตัวอย่างเซสชันที่ใช้dc:

$ dc
1 2 + p    # This part is typed; the result comes next.
3
q  # This is also typed.
$

หรือไม่โต้ตอบ:

$ dc -e '1 2 + p'
3
$
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.