awk 특정 행을 열로 바꾸고 그룹화합니다.

awk 특정 행을 열로 바꾸고 그룹화합니다.

표준 출력에는 다음 데이터가 있습니다.

13:46:17 0.8 cpu(1)
13:46:17 0.7 cpu(2)
13:46:17 1.1 cpu(3)
13:46:24 0.6 cpu(1)
13:46:24 0.5 cpu(2)
13:46:24 0.9 cpu(3)
13:46:31 0.8 cpu(3)
13:46:38 0.9 cpu(3)
13:46:52 0.5 cpu(1)
13:46:52 0.8 cpu(3)
13:46:59 0.6 cpu(1)
13:46:59 0.9 cpu(3)
13:47:06 0.6 cpu(2)
13:47:13 0.5 cpu(2)


이 스크립트를 사용하면 다음과 같은 결과를 얻을 수 있습니다.

['Time', 'cpu(1)', 'cpu(2)', 'cpu(3)'],
['13:46:17', 0.8, 0.7, 1.1],
['13:46:24', 0.6, 0.5, 0.9],
['13:46:31', , , 0.8],
['13:46:38', , , 0.9],
['13:46:52', 0.5, , 0.8],
['13:46:59', 0.6, , 0.9],
['13:47:06', , 0.6, ],
['13:47:13', , 0.5, ]

아래와 같은 예가 필요합니다.13시 46분 31초에 CPU(1) 값이 없으면 이전 CPU(1) 값을 새 타임스탬프에 복사해야 합니다.

['Time', 'cpu(1)', 'cpu(2)', 'cpu(3)'],
['13:46:17', 0.8, 0.7, 1.1],
['13:46:24', 0.6, 0.5, 0.9],
['13:46:31', 0.6, 0.5, 0.8],
['13:46:38', 0.6, 0.5, 0.9],
['13:46:52', 0.5, 0.5, 0.8],
['13:46:59', 0.6, 0.5, 0.9],
['13:47:06', 0.6, 0.6, 0.9],
['13:47:13', 0.6, 0.5, 0.9]

스크립트:

$ cat tst.awk
BEGIN {
    OFS = ", "
}
!seenTimes[$1]++ {
    times[++numTimes] = $1
}
!seenCpus[$3]++ {
    cpus[++numCpus] = $3
}
{
    vals[$1,$3] = $2
}
END {
    printf "[\047%s\047%s", "Time", OFS
    for ( cpuNr=1; cpuNr<=numCpus; cpuNr++ ) {
        cpu = cpus[cpuNr]
        printf "\047%s\047%s", cpu, (cpuNr<numCpus ? OFS : "]")
    }

    for ( timeNr=1; timeNr<=numTimes; timeNr++ ) {
        time = times[timeNr]
        printf ",%s[\047%s\047%s", ORS, time, OFS
        for ( cpuNr=1; cpuNr<=numCpus; cpuNr++ ) {
            cpu = cpus[cpuNr]
            val = vals[time,cpu]
            printf "%s%s", val, (cpuNr<numCpus ? OFS : "]")
        }
    }
    print ""
}

노트:스크립트 형식보다 간단한 스크립트를 요청하세요

답변1

$ cat tst.awk
BEGIN {
    OFS = ", "
}
!seen[$1]++ {
    times[++numTimes] = $1
}
!seen[$3]++ {
    cpus[++numCpus] = $3
}
{
    vals[$1,$3] = $2
}
END {
    printf "[\047%s\047%s", "Time", OFS
    for ( cpuNr=1; cpuNr<=numCpus; cpuNr++ ) {
        cpu = cpus[cpuNr]
        printf "\047%s\047%s", cpu, (cpuNr<numCpus ? OFS : "]")
    }

    for ( timeNr=1; timeNr<=numTimes; timeNr++ ) {
        time = times[timeNr]
        printf ",%s[\047%s\047%s", ORS, time, OFS
        for ( cpuNr=1; cpuNr<=numCpus; cpuNr++ ) {
            cpu = cpus[cpuNr]
            val = ( (time,cpu) in vals ? vals[time,cpu] : prev_vals[cpu] )
            printf "%s%s", val, (cpuNr<numCpus ? OFS : "]")
            prev_vals[cpu] = val
        }
    }
    print ""
}
$ awk -f tst.awk file
['Time', 'cpu(1)', 'cpu(2)', 'cpu(3)'],
['13:46:17', 0.8, 0.7, 1.1],
['13:46:24', 0.6, 0.5, 0.9],
['13:46:31', 0.6, 0.5, 0.8],
['13:46:38', 0.6, 0.5, 0.9],
['13:46:52', 0.5, 0.5, 0.8],
['13:46:59', 0.6, 0.5, 0.9],
['13:47:06', 0.6, 0.6, 0.9],
['13:47:13', 0.6, 0.5, 0.9]

전체 스크립트를 한 줄로 작성하려면 각 개행 문자를 ;.

관련 정보