awk를 통해 열 항목을 처리하는 데 도움이 필요합니다. 내가 시도하고 싶은 것은 다음과 같습니다.
- 사용자가 정의한 블록 크기로 열을 나눕니다.
- 각 블록의 각 항목이 계산되고 합산되어 각 항목의 평균이 최종 블록 크기가 됩니다.
예를 들어 다음은 목록입니다.
1
2
3
4
5
6
7
8
9
10
11
12
여기서는 블록 크기 4를 사용하고 싶습니다(그러나 제 경우에는 상황에 따라 다를 수 있습니다).
- 블록 1
1 2 3 4
- 블록 2
5 6 7 8
- 블록 3
9 10 11 12
처리 후 다음을 원합니다.
5
6
7
8
이는 모든 블록에서 1, 2, 3, 4위 항목의 평균입니다.
답변1
다음 awk
프로그램이 작업을 수행합니다. 데이터가 data.txt
첫 번째 열에 저장되어 있다고 가정합니다(그러나 다른 열에 쉽게 적용할 수 있음). 또한 빈 열은 없고 완전한 블록만 있다고 가정합니다.
awk -v cs=4 '{if ((i=NR%cs)==0) {n_ch++; i=cs};buf[i]+=$1;} END{for (i=1;i<=cs;i++) printf "%d\n",buf[i]/n_ch}' data.txt
awk
블록 크기는 명령문을 통해 전달됩니다.-v cs=size
각 행에 대해 "블록 내의 항목 번호"를 결정하고 을 i
전달
i = "line number" modulo "chunk size"
하고 항목을 배열로 합산합니다 buf
. 블록이 완료될 때마다 블록 카운터가 n_ch
증가합니다.
마지막으로 모든 항목 수의 평균을 인쇄합니다.
답변2
awk -v cs=4 '
BEGIN {
"(wc -l <" ARGV[1] ")" | getline nl
nc = sprintf("%d", nl/cs)
}
{ a[NR%cs] += $1 }
NR>nl-cs { print a[NR%cs]/nc }
' file
5
6
7
8
- 시작 블록에서 파일의 행을 결정하고 이를 nl 변수에 저장합니다.
- 그런 다음 블록 수를 가져와 nc 변수에 저장합니다.
- 누적 합계를 배열 인덱스 모듈로 행 번호 % 블록 크기에 누적합니다.
- 그런 다음 줄 번호가 nl-cs의 임계값을 초과하면(마지막 블록에 진입한다는 의미) 결과 인쇄가 시작됩니다.
또는 파일 길이와 블록 수를 미리 계산하지 않으려면 다음을 수행할 수 있습니다.
awk -v cs=4 '
{ a[NR] = $1 }
END {
for (i=1; i<=cs; i++) {
k = s = 0
for (j=i; j<=NR; j+=cs) {
s += a[j]; k++
}
print s/k
}
}
' file
답변3
또 다른 접근 방식 awk
은 실행 중에 각 블록의 요소를 계산하는 것입니다. 따라서 레코드 수가 블록의 정확한 배수가 아니더라도 여전히 평균입니다.
awk -v ch=4 '{k=(NR-1)%ch; n[k]++; un[k]+=$1}
END{for (k in un) print "Line "k+1" has "n[k]" elements totalling "un[k]" and average "un[k]/n[k]}' file
Line 1 has 3 elements totalling 15 and average 5
Line 2 has 3 elements totalling 18 and average 6
Line 3 has 3 elements totalling 21 and average 7
Line 4 has 3 elements totalling 24 and average 8
비록 END
설명적일 필요는 없지만
END{for (k in un) print un[k]/n[k]}' file
5
6
7
8
출력 순서를 보장하고 싶은 경우
END{for (k=0; k<ch; k++) print un[k]/n[k]}' file