Bash işlevlerini kullanarak komut satırında basit matematik işlemi yapmak: $ 1 bölü 2 $ (belki bc kullanarak)


33

Bazen bir sayıyı diğerine bölmem gerekir. Bunun için bir bash işlevi tanımlayabilseydim harika olurdu. Şimdiye kadar, gibi ifadeler kullanmak zorundayım

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

ancak benzeyen bir .bashrc işlevi tanımlayabilirsem çok iyi olurdu.

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

Yanıtlar:


45

Ben denilen kullanışlı bir bash işlevi var calc:

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

Örnek kullanım:

$ calc 65320/670
97.49253731343283582089

$ calc 65320*670
43764400

Bunu kendinize göre değiştirebilirsiniz. Örneğin:

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

Not: Burada stdin içine beslenen <<<bir dizedirbc . Çağırmana gerek yok echo.


3
İlave yankı atılmadan daha iyi göründüğünü kabul ediyorum, ancak kabuklu bir yapı olduğundan, fazladan ya da ek bir masrafla gelmiyor. '<<<' yi kabuk fonksiyonlarında kullanmamı engelleyen şey, bash ile olan sınırlamasıdır, ek yankı ise değiştirmeden orijinal burur kabuğunda veya ksh kullanılmasına izin verir.
Tatjana Heuser,

@TatjanaHeuser ksh, 93 çeşidi, burada dizeleri desteklemektedir.
Kusalananda

Bir değişkene atamak için şunu yaptım: foo = $ (bc -l <<< "(2 * 5) + 5")
thebiggestlebowski

20

Bash bir dereceye kadar matematiği kendisi yapabilir. Olsa bile, doğruluk için yararlı değildir.

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

Ama kesinlikle haklısın - bir bash işlevi basit bir kısayol olur ve örneğiniz temelde çalışır.

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

Bunu .bashrc'inize atın ve sonra şunları yapabilirsiniz:

[user]$ divide 10 5
2.0000000000000000000000000

1
echo $((10 / 5))tırnak gerektirmez.
kullanıcı bilinmeyen

1
Önemli sıkıntı: echo $((6383/7671)) size sıfır verecektir. Kayan nokta sayıları konusunda açık olmanız gerekir:echo $((6383.0/7671.0))
Sridhar Sarnobat

9

Muhtemelen bash 'expr' içinde olduğu gibi biliyorsunuz

$ expr 60 / 5
12

tamsayılarla sınırlıdır ve argümanlar arasındaki boşluklara ihtiyaç duyar.

Zaten kullanmakta olduğunuz yankı ifadesinin çizgileri boyunca bir işlev tanımlamaktan alıkoyan nedir? yani

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

1
sadece cehalet. bu şekilde çalışabileceğimin farkında değildim ...
ixtmixilix

7

Bu kesin sorunun cevabı değil, bilmek güzel olabilir. Kullanın zsh;-)

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

Aslında bu soruyu aradım çünkü zsh olarak değiştim ve bash'in expryerleşikini kullanamadım , ne olursa olsun iyi cevap verdim :)
Steen Schütt

2

Eğer varsa calcsisteminizde yüklü ve yuvarlanması sevmiyorum şunları yapabilirsiniz:

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

hmm ... 'calc' için herhangi bir debian paketi bulunamadı
ixtmixilix

Paket denir apcalc (Arbitary Precision) ... İkili olarak adlandırılırcalc
Peter.O

@ Peter.O Tamam, Arch Linux depolarında buna denir calc.

2

Küçük değerler için kirli bir kesmek ve bc kullanmadan sınırlı bir kesinlik, adayı bölmeden önce çarpmak, doğru bir sonuç elde etmek olacaktır.

Kesinlik olmadan örnek:

echo $((13/7)) 
1

ve 2 hane hassasiyetinde: 100 ile çarpın ve ondalık noktayı 2 adım sola hareket ettirin:

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

Bu, yalnızca sayıların aralığı önceden bilinirse ve kesinlik daima aynı ise faydalıdır. Çağrı için kaçınmak bc ve görüşmesi özelliğini sed çok makul görünmemektedir.

Değerleri çarpmanın taşma hatalarına neden olabileceğini, ancak çok erken olmadığını unutmayın:

echo $((1000000000*12345678901))
-6101065172709551616

Matematik ifadelerini değerlendirmek için çift parantez kullanmak, kullanımdan kaldırılmıştır. Kullanın: $[expression]Bunun yerine
laebshade

3
@ laebshade: Yanlış olduğunu kanıtlayabilirim, tam tersi doğrudur. Bash el kitabının bir alıntı:The old format $[expression] is deprecated and will be removed in upcoming versions of bash.
kullanıcı bilinmeyen

Ayrıca burada ,  burada  ve  burada tartışıldı .
G-Man

0

Bc kullanmak yerine, awk kullanabilirsiniz:

div() { awk -v p=$1 -v q=$2 'BEGIN{print p/q}'; }

-4
echo Division
efgh=$num1/$num2
remainder=$num1%num2
echo $num1 "/" $num2 "=" $efgh.$remainder
echo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.