Verwendung Awk eine Datei zu verarbeiten, wobei jeder Datensatz verschiedene Felder mit fester Breite hat

StackOverflow https://stackoverflow.com/questions/1393489

Frage

Ich habe einige Datendateien aus einem Altsystem, dass ich mag mit Awk verarbeiten. Jede Datei besteht aus einer Liste von Datensätzen. Es gibt mehrere verschiedene Datensatztypen und jeden Datensatztyp hat einen anderen Satz von Feldern mit fester Breite (es gibt keine Feldtrennzeichen). Die ersten beiden Zeichen des Datensatzes zeigen die Art, von dem aus Sie dann wissen, welche Felder folgen sollte. Eine Datei könnte wie folgt aussehen:

AAField1Field2LongerField3
BBField4Field5Field6VeryVeryLongField7Field8
CCField99

Mit Gawk ich einstellen kann der FIELDWIDTHS , aber das gilt für die gesamte Datei (es sei denn, ich auf einem Rekord-by-Rekord bin fehlt eine Möglichkeit, dies zu Einstellung Basis), oder ich kann zu einem Zeitpunkt FS auf „“ und Prozess die Datei ein Zeichen gesetzt, aber das ist ein bisschen beschwerlich.

Gibt es eine gute Möglichkeit, die Felder aus einer solchen Datei mit Awk?

zu extrahieren

Bearbeiten : Ja, ich könnte verwenden Perl (oder etwas anderes). Ich bin gespannt, noch zu wissen, ob es eine vernünftige Art und Weise ist es aber mit Awk zu tun.

War es hilfreich?

Lösung

Hoffentlich werden Sie in die richtige Richtung führen. Angenommen, Ihre Aufzeichnungen mit mehreren Leitungen sind garantiert durch einen ‚CC‘ Typ Zeile beendet werden können Vorprozess Textdatei if-then Logik einfach. Ich habe angenommen, Sie benötigen fields1,5 und 7 auf einer Zeile und einer Probe awk Skript wäre.

BEGIN {
        field1=""
        field5=""
        field7=""
}
{
    record_type = substr($0,1,2)
    if (record_type == "AA")
    {
        field1=substr($0,3,6)
    }
    else if (record_type == "BB")
    {
        field5=substr($0,9,6)
        field7=substr($0,21,18)
    }
    else if (record_type == "CC")
    {
        print field1"|"field5"|"field7
    }
}

Eine awk Skriptdatei namens program.awk und Pop diesen Code hinein. Führen Sie das Skript mit:

awk -f program.awk < my_multi_line_file.txt 

Andere Tipps

Sie können vielleicht zwei Pässe verwenden:

1step.awk

/^AA/{printf "2 6 6 12"    }
/^BB/{printf "2 6 6 6 18 6"}
/^CC/{printf "2 8"         }
{printf "\n%s\n", $0}

2step.awk

NR%2 == 1 {FIELDWIDTHS=$0}
NR%2 == 0 {print $2}

Und dann

awk -f 1step.awk sample  | awk -f 2step.awk

Sie haben wahrscheinlich zu unterdrücken müssen (oder zumindest ignorieren) awk des integrierten Feldtrenncode, und verwenden Sie ein Programm entlang der Linien von:

awk '/^AA/ { manually process record AA out of $0 }
     /^BB/ { manually process record BB out of $0 }
     /^CC/ { manually process record CC out of $0 }' file ...

Die manuelle Bearbeitung wird etwas schwierig sein kann - ich nehme an, Sie müssen die substr Funktion verwenden, um jedes Feld von Position zu extrahieren, so was ich habe als eine Zeile pro Satzart mehr wie eine Zeile pro Feld sein wird, in jedem Datensatz-Typ sowie die Folge auf Druck.

Ich glaube, besser könnte aus seinem mit Perl und seiner unpack Funktion, aber awk kann es zu handhaben, wenn auch verbosely.

Könnten Sie Perl verwenden und dann eine auspacken Vorlage auswählen, basierend auf den ersten beiden Zeichen der Zeile?

Bessere einige voll funktionsSkriptSprache wie Perl oder Ruby verwenden.

Was ist 2-Skripte? Z.B. 1. Skript Einsätze Feldtrenn basierend auf den ersten Zeichen, dann die zweite sollte es verarbeiten?

oder in erster Linie eine Funktion in Ihrem AWK Skript zu definieren, die die Linien in Variablen teilt auf der Grundlage der Eingabe -. Ich würde diesen Weg gehen, für die mögliche Wiederverwendung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top