한 열의 여러 값을 상수로 나누는 방법은 무엇입니까?

한 열의 여러 값을 상수로 나누는 방법은 무엇입니까?

두 열의 값을 어떤 상수로 나누려고 합니다. 그러나 각 열에는 콜론으로 구분된 여러 값이 있습니다. 파일이 매우 큽니다(24개 파일, 각각 2~3GB). 예를 들어 내 파일의 레이아웃은 다음과 같습니다.

1   18  N   112:0:0:0:0:0   126:0:0:0:0:0   19:0:0:0:0:0    20:0:0:0:0:0
1   19  N   0:0:114:0:0:0   0:0:136:0:0:0   0:0:18:0:0:0    0:0:19:0:0:0
1   20  N   0:112:0:0:0:7   0:125:0:0:0:20  0:16:0:0:0:3    0:13:0:0:0:5

출력이 다음과 같기를 원합니다.

1   18  N   56:0:0:0:0:0    63:0:0:0:0:0    19:0:0:0:0:0    20:0:0:0:0:0
1   19  N   0:0:57:0:0:0    0:0:68:0:0:0    0:0:18:0:0:0    0:0:19:0:0:0
1   20  N   0:56:0:0:0:3.5  0:62.5:0:0:0:10 0:16:0:0:0:3    0:13:0:0:0:5

답변1

(@berndbausch의 사용법 아이디어 반복 split) awk에는 배열을 다시 문자열로 평면화하는 기본 제공 방법이 없기 때문에 이것은 완전히 간단하지 않습니다. 우리는 printf를 사용해야 하며 그 결과 awk는 출력을 잘 정렬하는 방법을 잊어버립니다.

하지만 작동합니다.

#! /usr/bin/gawk -f

function print_div2(arr) {
    split(arr, a, ":")
    printf(" %d", a[1]/2)
    delete a[1]
    for(i in a) printf(":%d", a[i]/2)
}

{
    ORS=""
    print $1, $2, $3 " "
    print_div2($4)
    print " "
    print_div2($5)
    print " "
    ORS="\n"
    print $6, $7
}

print참고: ORS는 각 레코드를 처리할 때까지 줄 바꿈을 억제하는 데 사용됩니다 . 필드 4와 5를 print_div2 함수에 할당합니다. 이 함수는 레코드를 배열로 분할하고 각 항목의 절반을 인쇄합니다.

파일에 넣고 실행 가능으로 표시하십시오. 사용 예:

$ ./process.awk data.txt
1 18 N  56:0:0:0:0:0  63:0:0:0:0:0 19:0:0:0:0:0 20:0:0:0:0:0
1 19 N  0:0:57:0:0:0  0:0:68:0:0:0 0:0:18:0:0:0 0:0:19:0:0:0
1 20 N  0:56:0:0:0:3  0:62:0:0:0:10 0:16:0:0:0:3 0:13:0:0:0:5

다음 명령을 사용하여 깔끔한 열 정렬을 복원할 수 있습니다 column.

$ ./process.awk data.txt | column -t
1  18  N  56:0:0:0:0:0  63:0:0:0:0:0   19:0:0:0:0:0  20:0:0:0:0:0
1  19  N  0:0:57:0:0:0  0:0:68:0:0:0   0:0:18:0:0:0  0:0:19:0:0:0
1  20  N  0:56:0:0:0:3  0:62:0:0:0:10  0:16:0:0:0:3  0:13:0:0:0:5

답변2

awk '
    function dyd(col, n){
        split(col, t, ":");
        sep=":";
        return t[1]/n sep t[2]/n sep t[3]/n sep t[4]/n sep t[5]/n sep t[6]/n;
    };
{ $4=dyd($4, 2); $5=dyd($5, 2); }1' infile |column -t

관련 정보