고정 너비 파일의 레코드 수정

고정 너비 파일의 레코드 수정

다음과 같이 구성된 고정 너비 파일이 여러 개 있습니다.

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

다음과 같이 수정해야 합니다.

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

즉, 열 #4의 레코드 수가 <= 11이면 10을 추가해야 합니다. 12에서 15 사이이면 열 3의 값을 B로 변경하고 번호 매기기는 열 4에서 1부터 시작해야 합니다. 16보다 큰 경우 열 3의 값을 C로 변경하고 열 4 #4에서 1부터 번호 매기기를 시작해야 합니다.

구체적인 수치는 예시일 뿐이며, 4열의 값은 최대 900까지입니다. 다른 열은 변경되지 않고 원래 고정 열 너비를 유지합니다.

파일에는 약 5000개의 레코드가 있고, 하위 폴더에는 약 5000개의 파일이 있으며, "데이터베이스"에는 약 50개의 하위 폴더가 있습니다.

답변1

멍하니해결책:

Record.awk 수정스크립트:

#!/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

용법:

awk -f modify_records.awk datafile3248.dat

산출:

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

답변2

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

산출:

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

관련 정보