averlon
Anmeldungsdatum: 18. Mai 2011
Beiträge: 286
|
Hallo, ich habe aus einer datei zahlen in en_US format: | av_loc_calc1=5.2
av_loc_calc2=5.3
|
Mit denen würde ich gerne rechnen (z.B. subtrahieren oder numerisch vergleichen). Bisher bin ich bei jedem versuch daran gescheitert, dass das nicht der umgebung entsprach (de_DE.UTF-8). | if (( av_loc_calc1 < av_loc_calc2 ))
then
echo "kleiner"
else
echo "nicht kleiner"
fi
|
Ich habe versucht variablen zu setzen:
Hat auch nicht geholfen. Beim programm bc war es genau umgekehrt. Das kann nur "." und wenn mir werte mit "," vorlagen dann gibt es dabei einen fehler. Wer kann mir bitte einen trick verraten Danke
|
TheDarkRose
Anmeldungsdatum: 28. Juli 2010
Beiträge: 3459
|
Ein
LANG=C ./skript.sh}}
funktioniert auch nicht?
|
averlon
(Themenstarter)
Anmeldungsdatum: 18. Mai 2011
Beiträge: 286
|
Hi,
ich habe mir mal ein testscript gebaut: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #!/bin/bash
set -o xtrace
av_loc_calc1=5.2
av_loc_calc2=5.3
if (( av_loc_calc1 < av_loc_calc2 ))
then
echo "kleiner"
else
echo "nicht kleiner"
fi
set +o xtrace
|
Is ja jetzt nicht so komplex. Aber dein vorschlag hat da keine wirkung gehabt. If wirft immer noch fehler aus. ./av_test_12.sh
5 av_loc_calc1=5.2
6 av_loc_calc2=5.3
8 (( av_loc_calc1 < av_loc_calc2 ))
./av_test_12.sh: Zeile 8: ((: 5.2: Syntaxfehler: Ungültiger arithmetischer Operator. (Fehlerverursachendes Zeichen ist ».2«).
12 echo 'nicht kleiner'
nicht kleiner
15 set +o xtrace und LANG=C ./av_test_12.sh
5 av_loc_calc1=5.2
6 av_loc_calc2=5.3
8 (( av_loc_calc1 < av_loc_calc2 ))
./av_test_12.sh: Zeile 8: ((: 5.2: Syntaxfehler: Ungültiger arithmetischer Operator. (Fehlerverursachendes Zeichen ist ».2«).
12 echo 'nicht kleiner'
nicht kleiner
15 set +o xtrace Nachdem ich nicht wirklich weiß was dein vorschlag tun soll habe ich das auch mit den zwei klammern versucht - kam mir zwar komisch vor aber! LANG=C ./av_test_12.sh}}
-su: ./av_test_12.sh}}: Datei oder Verzeichnis nicht gefunden Nur so nebenbei: | ./av_test_12.sh
5 av_loc_calc1=5,2
6 av_loc_calc2=5,3
8 (( av_loc_calc1 < av_loc_calc2 ))
10 echo kleiner
kleiner
15 set +o xtrace
|
Es liegt wirklich an den punkten.
|
TheDarkRose
Anmeldungsdatum: 28. Juli 2010
Beiträge: 3459
|
Jup, kurzes googlen bringt auch, das bash keine floats kann. Einfach bc verwenden ☺ | #!/bin/bash
av_loc_calc1=5.2
av_loc_calc2=5.3
if (( $(bc <<< "$av_loc_calc1 < $av_loc_calc2") == 1 ))
then
echo "kleiner"
else
echo "nicht kleiner"
fi
|
P.S.: Mein komischer Posting von oben, war ne fehlerhaft benutzte Forensyntax 😉
|
averlon
(Themenstarter)
Anmeldungsdatum: 18. Mai 2011
Beiträge: 286
|
Hi,
danke für die hilfe. Das mit bc kenne ich. Hatte ich ja geschrieben. Der geht aber nur für en_US und nicht für de_DE (also ,). Ich habe bisher mit bc gearbeitet. Man soll es nicht glauben was ich gemacht habe, aber es erschien mir der einzige weg. Ich habe jedesmal den inhalt der variablen mit umgewandelt - und umgekehrt. Das muss doch eleganter gehen - daher meine frage.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Bash kann generell nicht Nachkommastellen arbeiten. Zufällig richtige Ausgaben mit Komma sind eine Illusion:
| a=5,2; b=44; if (( a < b )); then echo "a kleiner b"; else echo "a nicht kleiner b"; fi
|
Kannst Du vorab den Wertebereich eingrenzen und die Zahlen so weit multiplizieren, dass es Ganzzahlen werden?
|
averlon
(Themenstarter)
Anmeldungsdatum: 18. Mai 2011
Beiträge: 286
|
gut - verstehe ich. Aber dafür gibt es ja so programme (oder commanline tools) wie bc. Nur steht ja auch in der manpage von bc, dass bc die variablen für die spracheinstellungen nicht beachtet, zumindest in der 1.6 die in ubuntu verfügbar ist. Stellen wir die frage mal anders, denn aktuell kann ich ja mit dem "tr" leben - auch wenn ich das eher umständlich finde: Gibt es ein tool (commandline) mit dem man gleitkommaberechnungen machen kann und dem man sowohl "," als auch "." übergeben kann. Falls man dann z.B. eine sprachvariable vorher setzen muss - auch gut. Wenn es ein solches progrämmchen gibt - wie wird es dann genutzt (beispiel erwünscht)? Um den Hintergrund zu erklären: Ich werte eine Grundwassermessstelle aus. Das messgeraet stellt die daten in verschiedenster form zur verfügung. Leider: einmal haben die werte einen "." und einmal haben sie ein "," (warum auch immer). Und ich bin permanent mit "tr" am umwandeln. 22.05.2015 06:00:00 504.790 m
22.05.2015 10:00:00 504.792 m
22.05.2015 14:00:00 504.793 m 23.05.2015 14:00;504,790;;3,270
23.05.2015 18:00;504,790;13,780;3,270
23.05.2015 22:00;504,790;;3,270
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Ein Programm, das beide Varianten "kann", wäre awk - allerdings auch nur mit einem Trick: track@lucid:~$ echo 5.3 5.4 | awk '{exit ($1 < $2)}' ; echo $? # hier wird ganz normal numerisch verglichen
1
track@lucid:~$ echo 5.3 5.2 | awk '{exit ($1 < $2)}' ; echo $?
0
track@lucid:~$ echo 5,3 5,4 | awk '{exit ($1 < $2)}' ; echo $? # Achtung: hier wird als String verglichen, nicht als Zahl !
1
track@lucid:~$ echo 5,3 5,2 | awk '{exit ($1 < $2)}' ; echo $?
0 LG, track
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
| 22.05.2015 06:00:00 504.790 m
22.05.2015 10:00:00 504.792 m
22.05.2015 14:00:00 504.793 m
23.05.2015 14:00;504,790;;3,270
23.05.2015 18:00;504,790;13,780;3,270
23.05.2015 22:00;504,790;;3,270
|
Da Zahlen, die auf runde 10 cm enden, nicht von endenden Nullen befreit werden, würde ich die Kommas/Punkte eliminieren und in cm rechnen. Das hat den Vorteil, dass nicht ständig bc gestartet werden muss. Die Elimination der Kommas (Punkte) kann ebenso wie die Berechnung dann in der Shell erfolgen. Generell wie Track AWK zu verwenden ist natürlich auch eine elegante Option.
|
Mooi
Anmeldungsdatum: 15. August 2014
Beiträge: 187
|
user unknown schrieb: Bash kann generell nicht Nachkommastellen arbeiten.
Das ist nicht ganz richtig: Mittels Builtin printf, kann die Bash sehr wohl Fließkommazahlen formatieren. Damit kann man also Deine Idee des Umrechnens auf eine kleinere Einheit verwirklichen. Empfehlen will ich das aber nicht, denn wahrscheinlich ist die komplette Aufgabe hinter dem Eingangspost, mit awk wesentlich einfacher, bequemer und schneller lösbar. (Komplett OT: Schön, dass hier auf https umgestellt wird.)
|
D630
Anmeldungsdatum: 24. Juli 2013
Beiträge: 329
|
Die ksh kann seit Version 93 Floatingpoint-Arithmetik und bietet aehnlich wie awk eine Menge mathematische Funktionen, die aus C bekannt sind. Zsh kann es daher auch. Wenn ksh oder zsh, dann wuerde ich einfachheitshalber alle Kommata in einem Durchgang durch Punkte ersetzen, und nicht fuer jedes Testpaar ein weiteres Kommando aufrufen oder Parameter Expansion anwenden. Im eigentlichen Testblock solltest Du LC_ALL auf C umstellen und die Variablen vorher als Float deklarieren.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Mooi schrieb: user unknown schrieb: Bash kann generell nicht Nachkommastellen arbeiten.
Pardon, da ist ja ein "mit" verloren gegangen. Besser, weil spezifischer wäre natürlich auch "rechnen" statt "arbeiten" gewesen.
Das ist nicht ganz richtig: Mittels Builtin printf, kann die Bash sehr wohl Fließkommazahlen formatieren. Damit kann man also Deine Idee des Umrechnens auf eine kleinere Einheit verwirklichen.
Wie das?
|
Mooi
Anmeldungsdatum: 15. August 2014
Beiträge: 187
|
Aus meinem Terminal:
| ~> Meter=5,3
~> # 3 Nachkommastellen erzwingen
~> Meter=$(printf %.3f $Meter)
~> # Komma entfernen
~> MilliMeter=${Meter/,}
~> # Kontrolle
~> echo $MilliMeter
5300
~>
|
Das bleibt aber eine Spielerei, die man nicht in einem Script benutzen sollte.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Mooi schrieb: Das bleibt aber eine Spielerei, die man nicht in einem Script benutzen sollte.
Wieso nicht?
|
Mooi
Anmeldungsdatum: 15. August 2014
Beiträge: 187
|
Das wäre mir zu viel Arbeit, die ganzen Nachteile dieser Fummelmethode aufzuzählen. Ich wollte lediglich aufzeigen, dass es zur Not geht. Der klare Titel dieses Threads, fordert gerade dazu heraus.
|