PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zahlenformat



Scripter
12-01-2005, 12:30
Hallo
Wie kann ich Zahlen im Format "8.885867E-0"
im Sinne von:

if [ $Wert2 -gt $Wert1 ] ; then

beim shell scripten miteinander vergleichen?
geht das direkt in der if-Anweisung oder muß ich die Zahlen zuvor erst konvertieren?

Danke im voraus.

Hans-Georg Normann
12-01-2005, 17:58
Auf Systemebene eher ungewöhgnlich. Wo bekommst du solche Zahlen her?

Auf Anhieb fällt mir nichts ein. Vielleicht kann's bc oder dc. Worst Case bleibt awk. Dann würde ich aber das ganze Shellscript in awk fassen. Erzähl mal genau, was du verarbeiten möchtest und was dein Proggi machen soll.

Wär doch gelacht, wenn wir das nicht hinbekommen :p

Hans

Scripter
13-01-2005, 11:15
Danke, daß du mir helfen willst.

Solche Zahlen gibt mir Nastran (FEM) aus.
Verschiebung von Punkten über die Zeit bei Schwingungen.
Um die Maximalwerte zu bekommen möchte ich schrittweiße drei Punkte (Werte) vergleichen...

hab mir überlegt mit sed oder awk das (E-01) mit ( * 0.1), das (E-02) mit ( * 0,01) usw. auszutauschen und mir dann das Produkt mit `expr $Wertx` in die Variable ausgeben zu lassen.
Kannst du mir sagen wie ich das machen kann?
Oder hast du eine bessere Idee?

(wäre wahrscheinlich mit anderen Sprachen einfacher, hab aber grad nichts anderes zur verfügung)

Hans-Georg Normann
13-01-2005, 22:46
Hat etwas längert gedauert. Fedora Core 3 und NVIDIA lassen grüßen. :mad:

Nun zu deinem Problem. Hört sich schwer nach Physik an. Ich schätze, du brauchst hohe Rechengnauigkeit, oder liege ich da falsch? In dem Fall würde ich zu bc tendieren, auch wenn ich damit so gut wie nichts gemacht habe.

Liegen die Daten als Textfile vor? Wenn ja, kannst du nicht mal ein Muster posten oder als File anhängen?

Hans

Scripter
14-01-2005, 07:52
Ein Teil einer solchen File sieht z.B. so aus:

$POINT ID =_______IDENTIFIED BY TIME_____________7
_0.000000E+00 G___1.000000E+00___0.000000E+00___8
-CONT-___________0.000000E+00___0.000000E+00___9
_1.570800E-02 G___9.999589E-01___0.000000E+00___10
-CONT-___________0.000000E+00___0.000000E+00___11
_3.141600E-02 G___9.998358E-01___0.000000E+00___12
-CONT-___________0.000000E+00___0.000000E+00___13
_4.712400E-02 G___9.995905E-01___0.000000E+00___14
-CONT-___________0.000000E+00___0.000000E+00___15

(im eigentlichen file sind die "_" -> Leerzeichen, werden hier aber nicht dargestellt)

Ich möchte einfach die Zahlen aus jeder zweiten Zeile, in der zweiten spalte miteinander vergleichen, um herauszufinden, wo das Maximum ist.
Jetzt hab ich aber rausgefunden, daß Shell scripte nur ganze Zahlen vergleichen können.
Hab es jetzt so versucht, daß ich mit cut die Zahl in 9.995905 und -01 aufsplitte, das Komma entferne, in Variablen übergebe und dann jedes für sich vergleiche...

Zuerst den hinteren Part und wenn der identisch ist, die Zahl vorne...sehr umständlich.
Tips zur vereinfachung?

Joghurt
14-01-2005, 14:04
Mit shell-skripten wirst du nur Probleme haben, da sie (ebenso wie expr) nur mit Ganzzahlen rechnen.

Ich würde dir empfehlen, dich in perl reinzuarbeiten. Du wirst vielleicht beim ersten Mal etwas länger brauchen, als wenn du ein Shellskript schreibst, da du ja noch perl lernen musst. Aber dieser Aufwand lohnt sich, wenn du später nochmal ähnliche Aufgaben hast. Perl wurde ursprünglich ja entwickelt, um Textdateien zu analysieren und auszuwerden (Perl = Practical Extraction and Report Language)

Ich schätze, nach ein paar Stunden einarbeitung wirst du dein neues Perl-Skript fertig haben.

Hans-Georg Normann
14-01-2005, 19:55
Ich verzweifele..... :confused:

zuerst einmal das Einfache: wenn du Text in die CODE Tags einfügst, bleiben auch die Leerzeichen erhalten. (oder einfach auf das # klicken)

dann sieht deine Datei so aus
POINT ID = IDENTIFIED BY TIME 7
0.000000E+00 G 1.000000E+00 0.000000E+00 8
-CONT- 0.000000E+00 0.000000E+00 9
1.570800E-02 G 9.999589E-01 0.000000E+00 10
-CONT- 0.000000E+00 0.000000E+00 11
3.141600E-02 G 9.998358E-01 0.000000E+00 12
-CONT- 0.000000E+00 0.000000E+00 13
4.712400E-02 G 9.995905E-01 0.000000E+00 14
-CONT- 0.000000E+00 0.000000E+00 15Ich versuche nun krampfhaft mit einem awk Script zu den richtigen Zahlen zu kommen. Der awk will ums Verrecken nicht die Dezimalzahlen richtig interpretieren. Ich poste deshalb mal, was ich bisher gemacht habe
// { FindMaximum() }

Begin {
fMax = 0.0
aNumber = 0.0
aExponent = 0
}

function FindMaximum() {
if ( $1 == "-CONT-") return 0
if ( $1 == "POINT" ) return 0
setNumber($3)
printf ("%-10s %-10s %15.10f %5d\n", $1, $3, aNumber, aExponent)
}

function setNumber(aValue) {
# gsub(".",",",aValue)
CONVFMT = "%.10f"
for (i <= length(aValue);1;i++) {
if (substr(aValue,i,1) == "E") {
aNumber = substr(aValue,1,i-1)
print aNumber
aExponent = substr(aValue, i+1)
break
}
if (i == 25) {
break
}
}
}Also aNumber und aExponent enthalten schon die richtigen Werte. aNumber wird aber wohl als String interpretiert. Wie kann ich den casten? Ich hoffe das weiß einer.
When a string must be converted to a number, the conversion is accomplished using strtod(3). A number is converted to a string by using the value of CONVFMT as a format string for sprintf(3), with the numeric value of the variable as the argument. However, even though all numbers in AWK are floating-point, integral values are always converted as integers. Thus, given


CONVFMT = "%2.2f"
a = 12
b = a ""Meine Testumgebung besteht aus den Dateien myData und myProg.awk. Aufruf und Ausgabe sehen momentan so aus
[hans@rosi my]$ awk --posix -f myProg.awk myData
1.000000
0.000000E+00 1.000000E+00 1,0000000000 0
9.999589
1.570800E-02 9.999589E-01 9,0000000000 -1
9.998358
3.141600E-02 9.998358E-01 9,0000000000 -1
9.995905
4.712400E-02 9.995905E-01 9,0000000000 -1
[hans@rosi my]$ War jetzt viel Stoff, aber ich hoffe viel hilft viel und es kann uns jemand auf die Sprünge helfen.

Hans

Scripter
15-01-2005, 11:32
Danke Hans-Georg,
hast dir richtig viel mühe gemacht.
Hab mir was zusammengebastelt und es scheint zu funtionieren.
(sehr unschön und um 3 ecken, aber es scheint zu gehen)

Also, nochmal herzlichen Dank!

Hans-Georg Normann
15-01-2005, 12:17
Nee ne, so einfach wirste mich nicht los ;) Ich wiil das jetzt wissen wie es geht, egal ob du die Lösung benötigst oder nicht. Ich weiss dass das gehen muss.

Ist denn hier keiner, der noch richtiges UNIX Handwerkszeug wie awk versteht? :(

Hans

RapidMax
16-01-2005, 16:09
Hast du zum casten schon mal ein versucht Null zu addieren (stringvar + 0)?

Gruss, Andy

Hans-Georg Normann
16-01-2005, 16:26
for (i <= length(aValue);1;i++) {
if (substr(aValue,i,1) == "E") {
aNumber = substr(aValue,1,i-1)
print aNumber
aExponent = substr(aValue, i+1)
break
} Also ich bekomme aNumber immer als Integer angezeigt. Da kann ich draufpacken was ich will, es ist Integer. Wie mache ich dem blöden Prog klar, dass da ein Floatingpoint steht?

Oder spielt mir hier die Internationalisierung einen Streich, weil Punkt und Komma verwechselt werden? Das Script erwarted Punkt als Dezimaltrennzeichen gibt dieses aber bei der Ausgabe mit Komma zurück

Hans