Addition in der bash

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Addition in der bash

Beitrag von Duff » 16.03.2008 11:49:19

Hallo,

wie kann ich unter der BASH am besten Zahlen addieren, die so aussehen: 23.03 + 20.00 + 34.25, usw.

Ich habe es jetzt mal so probiert, aber es müsste doch auch irgendwie mit expr oder so funktionieren.

Code: Alles auswählen

daniel@daniel-laptop:~$ cat /tmp/test.t | sed -ne 's/^.* \([1-9][0-9]\{0,1\}[0-9]\{0,1\}\),\([0-9]\{1,\}\).*$/\1.\2/p' | awk '{ad=ad+$1} END {print "Summe:",ad}'
Summe: 1033
Die Datei sieht so aus:

Code: Alles auswählen

daniel@daniel-laptop:~$ cat /tmp/test.t | sed -ne 's/^.* \([1-9][0-9]\{0,1\}[0-9]\{0,1\}\),\([0-9]\{1,\}\).*$/\1.\2/p' 72.35
126.70
9.77
25.00
8.88
44.95
34.75
350.00
10.58
305.00
50.00
Habe es schon mit einer for-Schleife probiert, bekomme es aber nicht hin.
Oh, yeah!

Cologne4711
Beiträge: 260
Registriert: 04.12.2006 11:37:59

Beitrag von Cologne4711 » 16.03.2008 12:30:10

Hallo,

die bash kann nur integer

So sollte es aber gehen

a=30.00
b=20.01
$summe=`echo "$a+$b" | bc`


MfG

Benutzeravatar
Kokopelli
Beiträge: 1156
Registriert: 08.01.2007 10:13:24
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von Kokopelli » 16.03.2008 12:38:27

Falls Du soetwas öfter brauchst, könntest Du evtl. eine andere Shell nutzen oder eben ein script von einer anderen shell ausführen lassen. Zb. zsh:

Code: Alles auswählen

[m@lime /home/m] echo $((10.2+2.9))                     Sun, 16.03 12:37 [inbox: 0]
13.1
[m@lime /home/m]                                        Sun, 16.03 12:37 [inbox: 0]
Beste Grüße, Kokopelli
--------------------------
"One must marvel that Godzilla never died laughing" (William Tsutsui)

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Beitrag von Duff » 16.03.2008 13:25:05

Ok, danke. Das mit dem Addieren funktioniert dann schonmal.

Aber wie mache ich das mit der for-Schleife?
Oh, yeah!

Benutzeravatar
Kokopelli
Beiträge: 1156
Registriert: 08.01.2007 10:13:24
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von Kokopelli » 16.03.2008 15:01:31

Duff hat geschrieben:Ok, danke. Das mit dem Addieren funktioniert dann schonmal.

Aber wie mache ich das mit der for-Schleife?
Warum bestehst Du denn auf einer for-Schleife? Da die bash nicht rechnen kann hier mal eine Möglichkeit für die zsh.... für die bash müsstest Du halt den $((...))-Teil entsprechend für bc oder ähnliches umschreiben.
Version 1: for-Schleife über alle Zeilen in der Datei.
Version 2: Falls die Datei auch anderes enthält wird hier nach 0-9*.0-9* ge-grep-t
Version 3: Ohne Schleife, dafür mit xargs und tr 8O
(leider funktioniert ein einfaches tr ... <file nicht, da das EOF dann mit addiert wird, was natürlich nicht funktioniert... alternativ zu xargs könnte man an der Stelle auch cut-ten)
Die Idee dabei: die Zeilen mit + konkateniert zu einem String verquirlen und dann an die für die Berechnung zuständige Instanz weitergeben. In Version 4 auch mal mit bc, müsste also auch in der bash funktionieren

Code: Alles auswählen

[m@lime /home/m] cat test
126.70
9.77
25.00
8.88
44.95
34.75
350.00
10.58
305.00
50.00 
[m@lime /home/m] result=0;for i in $(cat test);do result=$(($result + $i));done;echo $result
965.63                                                                                      
[m@lime /home/m] result=0;for i in $(grep -o '[0-9]*\.[0-9]*' test);do result=$(($result + $i));done;echo $result
965.63
[m@lime /home/m] echo $(($(xargs <test |tr ' ' '+')))
965.63    
[m@lime /home/m] echo $(xargs  <test |tr ' ' '+')|bc
965.63                                   
 
Beste Grüße, Kokopelli
--------------------------
"One must marvel that Godzilla never died laughing" (William Tsutsui)

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Beitrag von Duff » 16.03.2008 19:52:04

Unter der bash bekommt ich immer diesen Fehler beim ersten "String"/"Zahl":

Code: Alles auswählen

daniel@daniel-laptop:~/scripts$ result=0; for i in `cat test.t | sed -ne 's/^.* \([1-9][0-9]\{0,1\}[0-9]\{0,1\}\),\([0-9]\{1,\}\).*$/\1.\2/p'`;do result=$(($result + $i));done;echo $result
bash: 0 + 72.35: syntax error in expression (error token is ".35")
Oh, yeah!

Benutzeravatar
Kokopelli
Beiträge: 1156
Registriert: 08.01.2007 10:13:24
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von Kokopelli » 16.03.2008 20:06:36

Duff hat geschrieben:Unter der bash bekommt ich immer diesen Fehler beim ersten "String"/"Zahl":

Code: Alles auswählen

daniel@daniel-laptop:~/scripts$ result=0; for i in `cat test.t | sed -ne 's/^.* \([1-9][0-9]\{0,1\}[0-9]\{0,1\}\),\([0-9]\{1,\}\).*$/\1.\2/p'`;do result=$(($result + $i));done;echo $result
bash: 0 + 72.35: syntax error in expression (error token is ".35")
Die bash beherrscht $((mathematischer Ausdruck)) nicht für nicht-integer-Zahlen. Daher wirst Du mit zB bc arbeiten müssen.
Beste Grüße, Kokopelli
--------------------------
"One must marvel that Godzilla never died laughing" (William Tsutsui)

Benutzeravatar
finupsen
Beiträge: 1327
Registriert: 21.04.2004 20:07:05
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Dortmund
Kontaktdaten:

Beitrag von finupsen » 17.03.2008 00:33:27

> wie kann ich unter der BASH am besten Zahlen addieren, die so aussehen: 23.03 + 20.00 + 34.25, usw.

mit bc...

Code: Alles auswählen

$~ cat test
126.70
9.77

$~ for i in `cat test`;do a=$(echo "$a+$i"|bc) ;done;echo $a
136.47
mit awk geht das aber auch:

Code: Alles auswählen

$~ cat test
126,70
9,77

$~ cat test | awk '{ i+=$1 } END { printf "%.2f\n", i }'
136,47
Was mir aufgefallen ist: awk erkennt einen float mit , und bc mit .
Niemand hat vor eine zentrale Datensammelbehörde aufzubauen. Es handelt sich vielmehr um dezentrale IT-Systeme die miteinander vernetzt werden.
... und Wasser ist naß.

Benutzeravatar
Meillo
Moderator
Beiträge: 9267
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Beitrag von Meillo » 17.03.2008 08:07:59

finupsen hat geschrieben:mit bc...
der allerdings nicht vorhanden sein muss
mit awk geht das aber auch:
und awk ist auf jedem Unix vorhanden
Was mir aufgefallen ist: awk erkennt einen float mit , und bc mit .
Das liegt ziemlich sicher an den locales, die wohl nur awk auswertet (wenn ich vermute, dass LC_NUMERIC bei dir deutsch ist).
Zuletzt geändert von Meillo am 17.03.2008 13:46:24, insgesamt 1-mal geändert.
Use ed once in a while!

Benutzeravatar
finupsen
Beiträge: 1327
Registriert: 21.04.2004 20:07:05
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Dortmund
Kontaktdaten:

Beitrag von finupsen » 17.03.2008 12:58:36

@Meillo

Code: Alles auswählen

$~ LANG=de_DE; echo "1.2" | awk '{ printf "%f\n", $0 }'
1,000000

$~ LANG=en_EN; echo "1.2" | awk '{ printf "%f\n", $0 }'
1.200000
gut zu wissen ... tnx ;)
Niemand hat vor eine zentrale Datensammelbehörde aufzubauen. Es handelt sich vielmehr um dezentrale IT-Systeme die miteinander vernetzt werden.
... und Wasser ist naß.

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Beitrag von Duff » 17.03.2008 14:10:03

Ok, danke. Dann werde ich es wohl doch mit awk lösen ;-)
Oh, yeah!

Antworten