Datensätze in Dateien mit fester Breite ändern

Datensätze in Dateien mit fester Breite ändern

Ich habe mehrere Dateien mit fester Breite und folgender Struktur:

datafile3248.dat

HEAD
DESCRIPTION
NAME      1  A   8   X
NAME      2  A   8   X
NAME      3  A   9  XX
NAME      4  A   9  XX
NAME      5  A   9   Y
NAME      6  A  10   Y
NAME      7  A  11  XY
NAME      8  A  11  XZ
NAME      9  A  12   Z
NAME     10  A  13   Z
NAME     11  A  13   Z
NAME     12  A  13  YZ
NAME     13  A  14  ZZ
NAME     14  A  15   X
NAME     15  A  16  XX
NAME     16  A  16   X
NAME     17  A  16   Y
NAME     18  A  17  YY

Sie müssen folgendermaßen geändert werden:

HEAD
DESCRIPTION
NAME      1  A  18   X
NAME      2  A  18   X
NAME      3  A  19  XX
NAME      4  A  19  XX
NAME      5  A  19   Y
NAME      6  A  20   Y
NAME      7  A  21  XY
NAME      8  A  21  XZ
NAME      9  B   1   Z
NAME     10  B   2   Z
NAME     11  B   2   Z
NAME     12  B   2  YZ
NAME     13  B   3  ZZ
NAME     14  B   4   X
NAME     15  C   1  XX
NAME     16  C   1   X
NAME     17  C   1   Y
NAME     18  C   2  YY

Wenn die Nummer eines Datensatzes in Spalte 4 beispielsweise <= 11 ist, sollte 10 addiert werden; wenn sie zwischen 12 und 15 liegt, sollte der Wert von Spalte 3 in B geändert und die Nummerierung in Spalte 4 bei 1 begonnen werden; wenn sie >= 16 ist, sollte der Wert von Spalte 3 in C geändert und die Nummerierung in Spalte 4 bei 1 begonnen werden.

Die spezifischen Zahlen dienen nur als Beispiel, die Werte in Spalte Nr. 4 gehen bis 900. Alle anderen Spalten werden nicht geändert, es muss lediglich die ursprüngliche feste Spaltenbreite beibehalten werden.

Es gibt ungefähr 5000 Datensätze in einer Datei, 5000 Dateien in einem Unterordner und 50 Unterordner in der „Datenbank“.

Antwort1

gaffenLösung:

Datensätze ändern.awkSkript:

#!/bin/awk -f
function pr(s, new_val)  # returns new field value preserving formatting
{
    len = length(s)      # getting field length (including leading whitespaces)
    return sprintf("%"len"s", new_val)
}
BEGIN { 
    FPAT = "([[:space:]]*[[:alnum:]]+)"; OFS = ""   # representation of field value
}
NR > 2 {    # starting from the 3rd record
    if ($4 <= 11) {
        $4 = pr($4, $4+10)

    } else if ($4 >= 12 && $4 <= 15) { 
        $3 = pr($3,"B")
        $4 = pr($4, $4-11) 

    } else if ($4 >= 16) { 
        $3 = pr($3, "C") 
        $4 = pr($4, $4-15) 
    }
} 1

Verwendung:

awk -f modify_records.awk datafile3248.dat

Die Ausgabe:

HEAD
DESCRIPTION
NAME      1  A  18   X
NAME      2  A  18   X
NAME      3  A  19  XX
NAME      4  A  19  XX
NAME      5  A  19   Y
NAME      6  A  20   Y
NAME      7  A  21  XY
NAME      8  A  21  XZ
NAME      9  B   1   Z
NAME     10  B   2   Z
NAME     11  B   2   Z
NAME     12  B   2  YZ
NAME     13  B   3  ZZ
NAME     14  B   4   X
NAME     15  C   1  XX
NAME     16  C   1   X
NAME     17  C   1   Y
NAME     18  C   2  YY

Antwort2

Mit GNU awk:

awk -v FIELDWIDTHS='4 7 3 4 4' '
    NR>2 {
        if ($4 <= 11)
            $4 += 10
        else if ($4 >= 12 && $4 <= 15) { 
            $3 = "B"
            $4 -= 11
        }
        else if ($4 >= 16) { 
            $3 = "C"
            $4 -= 15
        }
        $3 = sprintf("%3s", $3)
        $4 = sprintf("%4d", $4)
    }
    1' datafile3248.dat

Ausgabe:

HEAD
DESCRIPTION
NAME       1   A   18    X
NAME       2   A   18    X
NAME       3   A   19   XX
NAME       4   A   19   XX
NAME       5   A   19    Y
NAME       6   A   20    Y
NAME       7   A   21   XY
NAME       8   A   21   XZ
NAME       9   B    1    Z
NAME      10   B    2    Z
NAME      11   B    2    Z
NAME      12   B    2   YZ
NAME      13   B    3   ZZ
NAME      14   B    4    X
NAME      15   C    1   XX
NAME      16   C    1    X
NAME      17   C    1    Y
NAME      18   C    2   YY

verwandte Informationen