Forum: PC-Programmierung AWK Werte aus zwei Zeilen zusammenführen


von Matthias (matthiasm)


Lesenswert?

Hi und guten Abend,

ich brauche Hilfe bei AWK. Es geht um folgende Eingabe:
1
0x00, 0x1F, 0x7F, 0xE0, 0x80, 0x80, 0x80, 0xC0, 0x7F, 0x1F, 
2
0x00, 0xC0, 0xF0, 0x18, 0x08, 0x08, 0x08, 0x38, 0xF0, 0xC0,
3
4
0x00, 0x00, 0x30, 0x60, 0x40, 0xFF, 0xFF, 0x00, 0x00, 0x00, 
5
0x00, 0x00, 0x08, 0x08, 0x08, 0xF8, 0xF8, 0x08, 0x08, 0x08,
6
7
...

die Werte aus jeweils der zweiten Zeile sollen hinter den Werten der 
ersten Zeile stehen.

quasi so:

aus ...
1
0x00, 0x1F, ... 
2
0x00, 0xC0, ...

wird ...
1
0x0000, 0x1FC0,

Ich würde dazu gerne AWK verwenden. Kleinere Dinge bekomme ich damit 
hin, hier scheitere ich allerdings...

Vielen Dank für eure Hilfe!

: Verschoben durch User
von Liam Z. (liz)


Lesenswert?

Lies die Wete ein, also for(i=1;i<=FN;i++)  x[i]=0+$FN und
dann in jeder 2ten Zeile, oder lies die nächste Zeile mit getline ein, 
und gib es kombiniert aus.

von Matthias (matthiasm)


Lesenswert?

Liam Z. schrieb:
> for(i=1;i<=FN;i++)  x[i]=0+$FN

Das verstehe ich grad leider überhaupt nicht. Die for() Schleife läuft 
alle Zeilen ab und packt mir jede Zeile in das Array x, oder?

Aber ich brauchs ja nicht Zeilenweise sondern Wert für Wert...

getline ist generell eine super Idee, aber auch hier springe ich ja nur 
zur nächsten Zeile. Ich brauch ja immer den jeweiligen Wert aus der 2. 
Zeile und muss dann wieder zurückspringen.

von Liam Z. (liz)


Lesenswert?

Danni probier mal folgendes

BEGIN { FS = ","; OFS=","; }
for(i=1;i<=NF;i++) x[i]=$i;
getline;  $0=$0;
for(i=1;i<=NF;i++) $i=$i+"-"+x[i];
print $0;
}

: Bearbeitet durch User
von Matthias (matthiasm)


Angehängte Dateien:

Lesenswert?

Hmm leider auch nicht ganz...

er nullt nun alles.

(siehe Anhang)

von Liam Z. (liz)


Lesenswert?

Es sollte dir aufzeigen wie es geht, keine fertige Losung, dachte du 
kennst dich etwas aus.
Hier ein funktionierender code.

BEGIN { FS = ","; OFS=","; }
{
for(i=1;i<=NF;i++) x[i]=$i;
getline; $0=$0; gsub("[ \t]*0x","");
for(i=1;i<=NF;i++) $i=x[i] $i
print $0;
}

: Bearbeitet durch User
von Matthias (matthiasm)


Lesenswert?

Läuft!! :)

Danke danke danke danke!!

Liam Z. schrieb:
> dachte du
> kennst dich etwas aus.

... das dachte ich auch ... fehlt wohl noch so einiges an Übung.

von Liam Z. (liz)


Lesenswert?

BEGIN { FS = ","; OFS=","; }
NF {
for(i=1;i<=NF;i++) x[i]=$i;
getline; $0=$0; gsub("[ \t]*0x","");
for(i=1;i<=NF;i++) $i=x[i] $i
print $0;
}

von RS (Gast)


Lesenswert?

Wenn man die Sache etwas systematischer angeht, stellt man fest, dass 
deine  Records aus 20 Feldern bestehen, die jeweils durch eine Leerzeile 
getrennt werden. Mit RS="" kannst du awk das entsprechend verklickern.

Der nächste Schritt wäre dann, die Werte in den Feldern 1 und 11 zu 
addieren, dann von Feld 2 und Feld 12, etc. Dabei ist zu beachten, dass 
die Feldern 1..10 quasi die Tausender- und Hunderterstelle

von RS (Gast)


Lesenswert?

Sorry, mein Browser hat rumgesponnen und den Beitrag vorzeitig 
abgeschickt... :-(

Wenn man die Sache etwas systematischer angeht, stellt man fest, dass
deine  Records aus 20 Feldern bestehen, die jeweils durch eine Leerzeile
getrennt werden. Mit RS="" kannst du awk das entsprechend verklickern.

Der nächste Schritt wäre dann, die Werte in den Feldern 1 und 11 zu
addieren, dann von Feld 2 und Feld 12, etc. Dabei ist zu beachten, dass
die Felder 1..10 quasi die Tausender- und Hunderterstelle des 
Ergebnisses enthalten und dementsprechend mit 0x100 multipliziert werden 
müssen.

Das passende awk-Programm würde dann also ungefähr so aussehen:
1
BEGIN { RS = "" }
2
3
{
4
  for (i = 1; i <= 10; ++i)
5
    printf("0x%04x, ", $i * "0x100" + $(i + 10))
6
}

von ./. (Gast)


Lesenswert?

Wieder nuex als Laien unterwegs.

von RS (Gast)


Lesenswert?

Da darfst du dann natürlich nicht fehlen.

von Ralf D. (doeblitz)


Lesenswert?

RS schrieb:
[...]
1
> BEGIN { RS = "" }
2
> 
3
> {
4
>   for (i = 1; i <= 10; ++i)
5
>     printf("0x%04x, ", $i * "0x100" + $(i + 10))
6
> }

Dein awk liest Hexzahlen ein?

Ich würde da einfach bei nacktem Text bleiben:
1
BEGIN {
2
    RS = ""
3
    FS = ",[ \t\n\r]*"
4
}
5
6
{
7
    words = (NF-1)/2
8
    for (i = 1; i <= words; ++i)
9
        printf("%s%s, ", $i, substr($(i + words), 3, 2))
10
    print ""
11
}

Die Variable words erhält dynamisch die Zahl der auszugebenden 
16bit-Worte, die Korrektur "-1" ist erforderlich, da ein leeres Feld am 
Ende des Records erkannt wird (OK, an sich wird das durch implizites 
truncating schon erledigt, aber ich bevorzuge es, so etwas explizit zu 
coden, man will das ja auch in 20 Jahren noch leicht modifizieren 
können).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.