
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