ทำคณิตศาสตร์อย่างง่ายบนบรรทัดคำสั่งโดยใช้ฟังก์ชัน bash: $ 1 หารด้วย $ 2 (อาจใช้ bc)


33

บางครั้งฉันต้องหารจำนวนหนึ่งด้วยอีก มันจะดีมากถ้าฉันสามารถกำหนดฟังก์ชัน bash สำหรับสิ่งนี้ได้ จนถึงตอนนี้ฉันถูกบังคับให้ใช้นิพจน์เช่น

echo 'scale=25;65320/670' | bc

แต่มันจะดีมากถ้าฉันสามารถกำหนดฟังก์ชั่น. bashrc ที่ดูเหมือน

divide () {
  bc -d $1 / $2
}

คำตอบ:


45

ฉันมีฟังก์ชั่นทุบตีที่มีประโยชน์ที่เรียกว่าcalc:

calc () {
    bc -l <<< "$@"
}

ตัวอย่างการใช้งาน:

$ calc 65320/670
97.49253731343283582089

$ calc 65320*670
43764400

คุณสามารถเปลี่ยนสิ่งนี้ให้เหมาะกับตัวเอง ตัวอย่างเช่น:

divide() {
    bc -l <<< "$1/$2"
}

หมายเหตุ: <<<เป็นที่นี่สตริงซึ่งจะถูกป้อนเข้า stdin bcของ echoคุณไม่จำเป็นที่จะเรียก


3
ฉันเห็นด้วยว่ามันดูดีขึ้นโดยไม่มีเสียงสะท้อนเพิ่มเติม แต่เนื่องจากมันเป็นตัวเชลล์มันจึงมาพร้อมกับค่าใช้จ่ายเพิ่มเติมเล็กน้อยถึงไม่มีเลย สิ่งที่ทำให้ฉันไม่สามารถใช้ '<<<' ในฟังก์ชั่นเชลล์คือข้อ จำกัด ในการทุบตีในขณะที่เสียงสะท้อนเพิ่มเติมอนุญาตให้ใช้มันในเชลล์ bourne ดั้งเดิมหรือ ksh โดยไม่มีการเปลี่ยนแปลง
Tatjana Heuser

@TatjanaHeuser kshตัวแปร 93 สนับสนุนสตริงที่นี่
Kusalananda

เพื่อกำหนดให้กับตัวแปรฉันทำสิ่งนี้: foo = $ (bc -l <<< "(2 * 5) + 5")
thebiggestlebowski

20

Bash สามารถทำคณิตศาสตร์ได้ในระดับหนึ่ง มันไม่ได้มีประโยชน์สำหรับความถูกต้อง แต่อย่างใด

[user]$ echo $(( 10/5 ))
2

แต่คุณพูดถูก - ฟังก์ชั่นทุบตีจะเป็นทางลัดอย่างง่ายและตัวอย่างของคุณก็ใช้ได้

divide() {
  echo "scale=25;$1/$2" | bc
}

โยนมันลงใน. bashrc ของคุณแล้วคุณสามารถ:

[user]$ divide 10 5
2.0000000000000000000000000

1
echo $((10 / 5))ไม่จำเป็นต้องมีใบเสนอราคา
ผู้ใช้ไม่ทราบเมื่อ

1
ความรำคาญที่สำคัญ: echo $((6383/7671)) จะทำให้คุณเป็นศูนย์ คุณจะต้องมีความชัดเจนเกี่ยวกับตัวเลขจุดลอยตัว:echo $((6383.0/7671.0))
Sridhar Sarnobat

9

คุณอาจรู้ว่าทุบตี builtin 'expr' เหมือนใน

$ expr 60 / 5
12

ซึ่ง จำกัด อยู่ที่จำนวนเต็มและต้องการเว้นวรรคระหว่างอาร์กิวเมนต์

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

 divide () {
   echo $1/$2 | bc
 }

1
แค่ไม่รู้ ฉันไม่ได้ตระหนักว่าฉันสามารถทำให้มันเป็นเช่นนั้นได้ ...
ixtmixilix

7

ไม่ใช่คำตอบสำหรับคำถามที่แม่นยำ แต่อาจเป็นการดีที่จะรู้ ใช้zsh;-)

% echo $((65320./670))
97.492537313432834

ฉันเป็นจริงมองหาคำถามนี้เพราะผมเปลี่ยนไป zsh และไม่สามารถใช้ทุบตีของexprbuiltin คำตอบที่ดีเพื่อไม่คำนึง :)
สตีSchütt

2

หากคุณcalcติดตั้งในระบบและไม่ชอบปัดเศษคุณสามารถ:

div() { calc "$1 / $2"; }

อืม ... ไม่พบแพ็คเกจ debian ใด ๆ สำหรับ 'calc'
ixtmixilix

แพคเกจเรียกว่าapcalc (ความแม่นยำ Arbitary) ... ไบนารีที่เรียกว่าcalc
Peter.O

@ Peter.O ตกลงใน Repos Arch calcลินุกซ์ก็เรียกว่า

2

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

ตัวอย่างที่ไม่มีความแม่นยำ:

echo $((13/7)) 
1

และด้วยความแม่นยำ 2 หลัก: คูณด้วย 100 และเลื่อนจุดทศนิยม 2 ขั้นไปทางซ้าย:

echo $((100*13/7)) | sed 's/..$/.&/'
1.85
echo $((100*13/7))%
185%

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

โปรดทราบว่าการคูณค่าอาจทำให้เกิดข้อผิดพลาดมากเกินไป แต่ไม่เร็วมาก:

echo $((1000000000*12345678901))
-6101065172709551616

การใช้วงเล็บคู่เพื่อประเมินนิพจน์ทางคณิตศาสตร์จะถูกคัดค้าน ใช้: $[expression]แทน
laebshade

3
@ laebshade: ฉันสามารถพิสูจน์ได้ว่าคุณผิดตรงข้ามเป็นจริง นี่คือการอ้างอิงของคู่มือทุบตี:The old format $[expression] is deprecated and will be removed in upcoming versions of bash.
ผู้ใช้ที่ไม่รู้จัก

นอกจากนี้ยังกล่าวถึงที่นี่ ,  ที่นี่  และ  ที่นี่
G-Man กล่าวว่า 'Reinstate Monica'


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