AWK: 사용자 정의 청크 크기로 열을 나누고 각 청크에 대한 각 항목의 개수를 합산하여 모든 청크에 대한 각 항목의 평균을 제공합니다.

AWK: 사용자 정의 청크 크기로 열을 나누고 각 청크에 대한 각 항목의 개수를 합산하여 모든 청크에 대한 각 항목의 평균을 제공합니다.

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

관련 정보