
Tenho vários arquivos de largura fixa com a estrutura assim:
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
Eles devem ser modificados desta forma:
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
ou seja, se o número de um registro na coluna 4 for <= 11, deverá adicionar 10; se estiver entre 12 e 15, deve alterar o valor da coluna #3 para B e começar a numerar na coluna #4 a partir de 1, se for >=16, deve alterar o valor da coluna #3 para C e começar a numerar na coluna #4 de 1.
Os números específicos são apenas para exemplo, os valores na coluna 4 vão até 900. Quaisquer outras colunas não são alteradas, basta manter as larguras fixas originais das colunas.
Existem cerca de 5.000 registros em um arquivo, 5.000 arquivos em uma subpasta e 50 subpastas no 'banco de dados'.
Responder1
ficar boquiabertosolução:
modificar_records.awkroteiro:
#!/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
Uso:
awk -f modify_records.awk datafile3248.dat
A saída:
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
Responder2
Com 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
Saída:
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