AWK Werte aus zwei Zeilen zusammenführen

OP #4718739
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!
OP #4718767
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.
#4719251
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;
}
Gast #4719883
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
Gast #4719886
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
}
#4720242
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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren