Wie kann ich mit bash zwei Zahlen addieren (subtrahieren usw.)?

90

Ich kann die Zahlen und die Bedienung lesen mit:

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

Aber dann scheitern alle meine Versuche, die Zahlen hinzuzufügen:

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

Lauf:

First number please
1
Second mumber please
2
Operation?
+

Ausgabe:

num1+num2

...oder...

echo $num1+$num2;;

# results in: 1+2    

...oder...

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

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

Scheint, als würde ich vielleicht immer noch Zeichenketten bekommen, wenn ich add add ("2 + 2" statt "4") versuche.

Michael Durrant
quelle
5
Ich habe Ihren Titel bearbeitet, weil dies eine gute allgemeine Frage ist, und wenn Sie den Kontext eingegrenzt hätten, hätten Sie gemerkt, dass dies nichts zu tun hat caseoder etwas anderes als eine Zeile:, echo $num+$numda dies das Problem genau reproduziert . Die Idee, den Kontext in Programmierfragen zu minimieren, wird hier erklärt: sscce.org
goldilocks
2
+1 Hallo Goldlöckchen, ja, das wurde mir später klar, aber ja, ich stimme Ihrer Argumentation voll und ganz zu und ja, je spezifischer und "singulärer" eine Frage ist, desto besser. Ich begrüße Ihre Bearbeitung (en) :) Vielen Dank :)
Michael Durrant

Antworten:

117

Arithmetik in POSIX-Shells erfolgt mit $und doppelten Klammern (( )):

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

Daraus können Sie zuweisen (ohne echo):

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

Es gibt auch expr:

expr $num1 + $num2

Bei der Skripterstellung $(())ist es vorzuziehen, da dadurch ein Fork / Execute für den exprBefehl vermieden wird .

Goldlöckchen
quelle
Oder auch direkt echo $(($num1$op$num2))ohne mitzumachen case.
Manatwork
Es ist hier nicht casebeteiligt.
Goldlöckchen
1
Nein, aber Sie haben ein Literal verwendet. Daher +muss die caseAußenseite für die Subtraktion separat behandelt werden.
Manatwork
1
@manatwork: Du meinst, das caseaus dem OP-Code entfernen mit echo $(($num1$op$num2))- das wird funktionieren, aber die Verwendung von caseist robuster, da du Fehler mit einem Standard behandeln kannst *.
Goldlöckchen
+1 an euch beide. Ich habe case verwendet (habe es zu Beginn möglicherweise nicht gezeigt), aber Sie haben beide festgestellt, dass es sich bei dem Problem nicht um den Fall handelt.
Michael Durrant
13

Die vorhandene Antwort ist pure bash, daher ist sie schneller als diese Antwort, kann jedoch nur Ganzzahlen verarbeiten. Wenn Sie mit Floats umgehen müssen, müssen Sie das externe Programm verwenden bc.

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

Das scale=4weist bcan, vier Dezimalstellen zu verwenden. Siehe man bcfür weitere Informationen.

Übelsuppe
quelle
Beachten Sie, dass während bashnicht arithmetics Floating - Point unterstützt mit $((...)), viele Muscheln ( ksh93, zsh, yashzumindest) tun. Der Vorteil von bcist, dass es eine beliebige Genauigkeit unterstützt, während die Shell-Arithmetik auf den Prozessortyp beschränkt ist double. Beachten Sie, dass Sie hier keine Einstellungen scalevornehmen müssen. Für Zusätze wird der scaleParameter nicht verwendet. Die Skala von 3.1415+9.99wird von der der Operanden abgeleitet (hier 4).
Stéphane Chazelas
Wie kann man rechnen, wenn ein Wert 450dezimal in einer Variablen gespeichert ist $mynumber? Zum Beispiel 450-$mynumber.
Sigur
@sigur echo "450-$mynumber" | bcsollte es tun. Wenn Sie möchten, dass eine Variable erweitert wird, müssen Sie doppelte Anführungszeichen anstelle von einfachen Anführungszeichen verwenden.
Evilsoup
@evilsoup, jetzt funktioniert es wie ein Zauber. Vielen Dank.
Sigur
computedval=$(echo 'scale=10;var1-var2' | bc)funktioniert nicht und auch nichtcomputedval=$(echo 'scale=10;$var1-$var2' | bc)
StatsSorceress
5
echo `expr $a + $b`   
echo `expr $a - $b`   
echo `expr $a \* $b`   
echo `expr $a / $b`   

Beachten Sie, dass \vor *(zur Multiplikation) der gesamte Ausdruck in Anführungszeichen stehen muss.

Himani
quelle
1
exprist nicht erforderlich, und es ist niemals erforderlich, die Standardausgabe eines Befehls zu erfassen, nur um sie in die Standardausgabe zurückzuschreiben.
Chepner
2

minimalistisch

total=0
((total+=qty))
geekzspot
quelle
1

Sie können auch $[ ... ]Struktur verwenden. In diesem Fall verwenden wir den in Bash integrierten Mechanismus, der schneller und etwas komfortabler zu bedienen ist. Da wir wissen, dass alles zwischen $ [und] als Ausdruck behandelt wird, müssen wir den Variablen keinen vorangestellten Wert voranstellen $. Ebenso müssen wir uns nicht davor *schützen, es wie ein Muster zu behandeln.

num1=2
num2=3
echo $[num1 + num2]
5
Jedi
quelle
0

Basierend auf der Reihenfolge der Eingaben, die Sie vom Benutzer anfordern, scheint es, dass Sie die umgekehrte polnische Notation verwenden.

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

Sie können es besser machen, wenn Sie nur dc(Tischrechner) direkt verwenden, da dies der Zweck ist.

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

Beispielsitzung mit dc:

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

Oder nicht interaktiv:

$ dc -e '1 2 + p'
3
$
Platzhalter
quelle