ubuntuusers.de

Bashskript: File einlesen und in bestimmten Format speichern

Status: Gelöst | Ubuntu-Version: Xubuntu 16.04 (Xenial Xerus)
Antworten |

KeyzerSoze

Anmeldungsdatum:
28. September 2014

Beiträge: 120

Hallo ubuntuusers, ich habe eine Datei (input.txt), die ungefähr so aussieht:

k= 0.00 0.00 0.00
 1  2  3  4  5  (5 Spalten)
 6  7  8  9 10  // "7" = 7. Element (nach der "k="-Zeile)
11 12 13 14 15

k= 0.00 0.00 0.01
 5  8  9  3 10
55 66 33  5 88  // "66" = ist 7. Element
 2 33 44  0  2

k= ... (noch 1000 Datenpunkte)

Von dieser Datei möchte ich ein File (output.txt) erzeugen, das immer das 7. Element aus dem File "input.txt" ausliest (in unserem Beispiel "7" und "66") und in folgender Form abspeichert:

7 66 x x x x (6 Spalten)
 x  x x x x x
 x  x x x x x
 x  x x x x x
...

Ich wollte mir ein Bashskript erstellen, ich habe aber einige Schwierigkeiten dabei: Kann ich irgendwie das "7." Element nach der "k="-Zeile direkt auslesen, oder muss ich das mittels der

awk  '{print $2}'

Ausgabe machen und mir dann immer die zweite Zeile speichern? Wie kann ich diese Elemente dann in ein 6-Spalten-File schreiben? Brauche ich da eine for-Schleife? Kann mir jemand weiterhelfen?

Danke im Voraus!

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Aus Deiner Beschreibung lese ich, dass Du im Prinzip 3 gestaffelte Zyklen haben willst:

  1. Wenn eine Zeile mit "k=" beginnt, soll die Zeilennummer neu gespeichert werden,

  2. 2 Zeilen später soll dann ein Leerzeichen und die Zahl in der 2. Spalte ausgegeben werden,

  3. Nach jeder 6. Ausgabe kommt eine neue Zeile (→ Zeilenumbruch). (und ganz am Ende auch nochmal)

Mit awk umgesetzt könnte das z.B. so aussehen:

track@track:~$ echo 'k= 0.00 0.00 0.00
 1  2  3  4  5  (5 Spalten)
 6  7  8  9 10  // "7" = 7. Element (nach der "k="-Zeile)
11 12 13 14 15

k= 0.00 0.00 0.01
 5  8  9  3 10
55 66 33  5 88  // "66" = ist 7. Element
 2 33 44  0  2'  |  awk '/^k=/{n=NR+2} NR==n {printf " %i",$2; b++} b==6 {print ""; b=0} END {print ""}'
 7 66 

Die Details findest Du recht hübsch in der awk-Einführung erklärt.

LG,

track

KeyzerSoze

(Themenstarter)

Anmeldungsdatum:
28. September 2014

Beiträge: 120

Hallo track, vielen Dank!, das hilft mir sehr weiter.

Jedoch bin ich mit 2 Punkten noch nicht ganz zufrieden:

1) In meinem richtigen File habe ich keine Integers mehr, sondern doubles. Wenn ich bei der printf-Funktion

%i durch %f

austausche, bekomme ich 6 Nachkommastellen, ich bräuchte aber mindestens 7, noch besser wäre eine double-Genauigkeit (10^(-16)).

 %g

ist noch ungenauer,

%e

hat die selbe Genauigkeit wie %f, zudem versteht das Leseprogramm nur das Format Zahl.Nachkommastellen und nicht 8.283682e+00. Long float %lf ändert leider auch nichts. Wie kann ich die Genauigkeit erhöhen?

2) Anders als im Beispiel habe ich zu jedem k-Punkt nicht nur 15 Datenpunkte, sondern um die 80. Ich finde es ein wenig umständlich (vielleicht auch fehleranfällig), wenn ich für verschiedene Elemente Zeilen- und Spaltennummer von Hand eingeben muss. Besser fände ich es, wenn ich nur sagen müsste, das mich Element 33 interessiert. Kann ich das noch iwie implementieren?

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

KeyzerSoze schrieb:

1) In meinem richtigen File habe ich keine Integers mehr, sondern doubles. Wenn ich bei der printf-Funktion

%i durch %f

austausche, bekomme ich 6 Nachkommastellen, ich bräuchte aber mindestens 7, noch besser wäre eine double-Genauigkeit (10^(-16))

Dann hattest Du ein falsches Beispiel gegeben ! - natürlich kannst Du bei printf auch eine konkrete Genauigkeit angeben, wenn Du die Zahlen überall mit der selben Auflösung / Darstellung haben willst. (das mit "%g" kannst Du vergessen, da unterscheidet awk mit Sicherheit nicht !)
Oder aber: Du nimmst die Zahlen einfach blind als String (" %s"), dann bleiben sie so wie sie vorher waren, und die ganzen Fragen der Auflösung können Dir egal sein. 😀

2) Anders als im Beispiel habe ich zu jedem k-Punkt nicht nur 15 Datenpunkte, sondern um die 80. Ich finde es ein wenig umständlich (vielleicht auch fehleranfällig), wenn ich für verschiedene Elemente Zeilen- und Spaltennummer von Hand eingeben muss. Besser fände ich es, wenn ich nur sagen müsste, das mich Element 33 interessiert.

Tja, awk kennt von Hause aus nun mal nur Zeilen und Spalten. Wenn Du das anders haben willst, dann müsstest Du selber was basteln. Aber ob das dann weniger fehleranfällig wird ?
Hier in meinem Beispiel ist es für awk egal, ob dahinter noch Kommentare ohne Ende stehen, weil es eh nur das 2. "Wort" nimmt. → Es kommt also durchaus darauf an, was die zuverlässige Konstante im Format der Rohdaten ist.

Statt im Nachhinein immer neue Nebenbedingungen durchsickern zu lassen, wäre sicherlich besser, wenn Du uns direkt die echte Problemstellung / echte Beipieldaten liefern würdest. Dann wüssten wir wenigstens, mit welchen Finten wir noch rechnen müssen.

LG,

track

KeyzerSoze

(Themenstarter)

Anmeldungsdatum:
28. September 2014

Beiträge: 120

1)

%s

ist super, danke ☺

2)

Statt im Nachhinein immer neue Nebenbedingungen durchsickern zu lassen, wäre sicherlich besser, wenn Du uns direkt die echte Problemstellung / echte Beipieldaten liefern würdest. Dann wüssten wir wenigstens, mit welchen Finten wir noch rechnen müssen.

Sorry ☺

Antworten |