Zeile basierend auf der vorherigen Zeile aktualisieren

Zeile basierend auf der vorherigen Zeile aktualisieren

Ich habe ein Problem, da ich mit awk nicht vertraut bin. Ich habe eine CSV-Datei, die aus der Ausgabe von sar -d generiert und in den CSV-Stil konvertiert wurde:

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
,iscsi0,0,0.0,0,0,0.0,0.0
,scsi_vhc,0,0.0,0,0,0.0,0.0
,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
,iscsi0,0,0.0,0,0,0.0,0.0
,scsi_vhc,0,0.0,0,0,0.0,0.0
,nfs1,0,0.0,0,0,0.0,0.0

und ich möchte dazu konvertieren

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
12:35:00,iscsi0,0,0.0,0,0,0.0,0.0
12:35:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:35:00,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
12:45:00,iscsi0,0,0.0,0,0,0.0,0.0
12:45:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:45:00,nfs1,0,0.0,0,0,0.0,0.0

Mein Versuch, aber da awk Zeile für Zeile liest, weiß ich nicht, wie ich den Wert der vorherigen Zeile beibehalten soll. Ich würde erwarten, dass das, was ich habe, funktionieren sollte. Irgendeine Idee, wie ich das gewünschte Ergebnis erzielen kann? Ich habe es mit awk versucht, aber ich denke, das sollte mit sed oder auf die harte Tour mit einem benutzerdefinierten Shell-Skript möglich sein (ich versuche, diesen Teil zu vermeiden).

#!/usr/bin/awk -f
BEGIN {
        FS=",";
}
{
        print $1
        if ($1 != "") {
                mydate=$1;
                print $0;
        }
        else {
                print $mydate","$0;
        }
}

Ausführen des Systems mit Solaris 11.1.

Antwort1

Es wird etwas lang, da die Eingabe scheinbar leere Zeilen enthält. Folgendes könnte für Sie funktionieren:

awk -F'[, ]' '{if (NF!=0 && $1=="") {$1=prev} prev=$1}1' OFS=, inputfile

Die Idee ist, Felder und Leerzeichen aufzuteilen ,(letzteres, um die erste Eingabezeile zu verarbeiten). Überprüfen Sie, ob das erste Feld leer istUnddie Anzahl der Felder ungleich Null ist (Leerzeilen behandeln), dann das erste Feld durch das zuvor gespeicherte erste Feld ersetzen.

Für Ihre Eingabe würde das Ergebnis lauten:

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
12:35:00,iscsi0,0,0.0,0,0,0.0,0.0
12:35:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:35:00,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
12:45:00,iscsi0,0,0.0,0,0,0.0,0.0
12:45:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:45:00,nfs1,0,0.0,0,0,0.0,0.0

Antwort2

Mit sed:

sed '/^[0-9]/{               # if line starts with digit
h                            # overwrite hold buffer with pattern space content
s/\([^,]*\),.*/\1/           # extract timestamp
x                            # exchange: put the original line back into pattern
}                            # space and the timestamp in hold space
/^,/{                        # if line starts with a comma
G                            # append hold space (timestamp) to pattern space
s/\(.*\)\n\(.*\)/\2\1/       # swap the initial line content and the timestamp 
}' infile

in einer Zeile:

sed -e'/^[0-9]/{h;s/\([^,]*\),.*/\1/;x' -e\} -e'/^,/{G;s/\(.*\)\n\(.*\)/\2\1/' -e\} infile

Antwort3

Ein anderer sed:

sed '$!N;/\n,/s/\([^,]*\).*\n/&\1/;P;D' <in >out

Für jede Eingabezeile, die !nicht die $letzte ist, wird die ext-Eingabezeile an den Musterraum sedangehängt , dem ein ewline-Zeichen vorangestellt ist. Anschließend wird ein Ersetzungsversuch unternommen, bei dem die erste mögliche Gruppe von Zeichen, die kein Komma sind, in den Raum direkt vor einem Komma kopiert wird, das unmittelbar auf eine ewline folgt. Wenn dies nicht möglich ist, ist wohl kein Schaden entstanden.N\ns///^,\n

sedwird dann bis zur ersten neuen Zeile im Musterbereich Pgedruckt und diese gelöscht, bevor der Zyklus mit dem nächsten Paar Eingabezeilen von vorne erneut begonnen wird.\nD

AUSGABE

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
12:35:00,iscsi0,0,0.0,0,0,0.0,0.0
12:35:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:35:00,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
12:45:00,iscsi0,0,0.0,0,0,0.0,0.0
12:45:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:45:00,nfs1,0,0.0,0,0,0.0,0.0

verwandte Informationen