awk를 사용하여 2D 배열의 여러 숫자를 합하는 방법

awk를 사용하여 2D 배열의 여러 숫자를 합하는 방법

다음과 같이 파일의 숫자를 합산해야 합니다.

       column1  column2 column3
 row1   a(1,1)   a(1,2)  a(1,3)
 row2   a(2,1)   a(2,2)  a(2,3)
 row3   a(3,1)   a(3,2)  a(3,3)
 row4   a(4,1)   a(4,2)  a(4,3)
 row5   a(5,1)   a(5,2)  a(5,3)
 row6   a(6,1)   a(6,2)  a(6,3)
 row7   a(7,1)   a(7,2)  a(7,3)
 row8   a(8,1)   a(8,2)  a(8,3)
 row9   a(9,1)   a(9,2)  a(9,3)
 row10  a(10,1)  a(10,2) a(10,3)
 row11  a(11,1)  a(11,2) a(11,3)
 row12  a(12,1)  a(12,2) a(12,3)


       column4  column5 column6
 row1  b(1,1)   b(1,2)  b(1,3)
 row2  b(2,1)   b(2,2)  b(2,3)
 row3  b(3,1)   b(3,2)  b(3,3)
 row4  b(4,1)   b(4,2)  b(4,3)
 row5  b(5,1)   b(5,2)  b(5,3)
 row6  b(6,1)   b(6,2)  b(6,3)
 row7  b(7,1)   b(7,2)  b(7,3)
 row8  b(8,1)   b(8,2)  b(8,3)
 row9  b(9,1)   b(9,2)  b(9,3)
 row10 b(10,1)  b(10,2) b(10,3)
 row11 b(11,1)  b(11,2) b(11,3)
 row12 b(12,1)  b(12,2) b(12,3)

출력은 다음과 같아야 합니다.

  column1    a(1,1)+a(2,1)+a(5,1)+a(6,1)+a(7,1)+a(8,1)+a(11,1)      a(3,1)+a(4,1)+a(9,1)+a(10,1)+a(12,1)  
  column2    a(1,2)+a(2,2)+a(5,2)+a(6,2)+a(7,2)+a(8,2)+a(11,2)      a(3,2)+a(4,2)+a(9,2)+a(10,2)+a(12,2) 
  column3    a(1,3)+a(2,3)+a(5,3)+a(6,3)+a(7,3)+a(8,3)+a(11,3)      a(3,3)+a(4,3)+a(9,3)+a(10,3)+a(12,3)
  column4    b(1,1)+b(2,1)+b(5,1)+b(6,1)+b(7,1)+b(8,1)+b(11,1)      b(3,1)+b(4,1)+b(9,1)+b(10,1)+b(12,1)
  column5    b(1,2)+b(2,2)+b(5,2)+b(6,2)+b(7,2)+b(8,2)+b(11,2)      b(3,2)+b(4,2)+b(9,2)+b(10,2)+b(12,2)
  column6    b(1,3)+b(2,3)+b(5,3)+b(6,3)+b(7,3)+b(8,3)+b(11,3)      b(3,3)+b(4,3)+b(9,3)+b(10,3)+b(12,3)

비슷한 작업을 수행할 수 있는 방법이 있지만 4행에서만 작동합니다. 이 스크립트를 수정해야 합니다.

sed 's/row[1-9]//;/^$/d' file |    #elimina os rows
pr -2t -w 1000| 
awk 'NR==1{$1=$1; print; next} 
 !(NR%2){split($0,a); next}          
        {for(i=1;i<=NF;i++) $i+=a[i]}1' | 
 tr ' ' '\n' | 
 pr -3t 

합계를 계산할 때 주의할 점

   $ tr -d 'ab(,)' < file > filenums

awk부분에서 수정이 필요하다고 생각하는데 어떻게 해야할지 모르겠습니다.

답변1

이것은 귀하의 질문에 대한 문자 그대로의 답변입니다 awk. 다음을 사용하십시오.

awk '
  /column4/ { c = 3 }   # add three for the second set of columns
  /row/ {
    row = substr($1,4)  # extract the row number
    col[1+c,row] = $2   # extract column 1 or 4, store in hash
    col[2+c,row] = $3   # extract column 2 or 5, store in hash
    col[3+c,row] = $4   # extract column 3 or 6, store in hash
  }
  END {
    split("1 2 5 6 7 8 11", out1) # create an array of first set of rows
    split("3 4 9 10 12", out2)    # create an array of second set of rows

    for (c = 1; c <= 6; c++) {
      out = sprintf("  column%d    %s", c, col[c,1]) # title and first row
      for (r = 2; r <= 7; r++) {
        out = out "+" col[c,out1[r]]                 # the rest of the first set
      }
      out = out "      " col[c,3]                    # spaces, 1st row of 2nd set
      for (r = 2; r <= 5; r++) {
        out = out "+" col[c,out2[r]]                 # the rest of the 2nd set
      }
      print out
    }
  }
' file

이 출력은 다음과 같습니다.

  column1    a(1,1)+a(2,1)+a(5,1)+a(6,1)+a(7,1)+a(8,1)+a(11,1)      a(3,1)+a(4,1)+a(9,1)+a(10,1)+a(12,1)
  column2    a(1,2)+a(2,2)+a(5,2)+a(6,2)+a(7,2)+a(8,2)+a(11,2)      a(3,2)+a(4,2)+a(9,2)+a(10,2)+a(12,2)
  column3    a(1,3)+a(2,3)+a(5,3)+a(6,3)+a(7,3)+a(8,3)+a(11,3)      a(3,3)+a(4,3)+a(9,3)+a(10,3)+a(12,3)
  column4    b(1,1)+b(2,1)+b(5,1)+b(6,1)+b(7,1)+b(8,1)+b(11,1)      b(3,1)+b(4,1)+b(9,1)+b(10,1)+b(12,1)
  column5    b(1,2)+b(2,2)+b(5,2)+b(6,2)+b(7,2)+b(8,2)+b(11,2)      b(3,2)+b(4,2)+b(9,2)+b(10,2)+b(12,2)
  column6    b(1,3)+b(2,3)+b(5,3)+b(6,3)+b(7,3)+b(8,3)+b(11,3)      b(3,3)+b(4,3)+b(9,3)+b(10,3)+b(12,3)

그러나 "합계 계산"을 사용한다고 말씀하셨는데 tr -d 'ab(,)', 무슨 뜻인지 모르겠습니다. 해당 명령은 사용자가 지정한 문자만 제거하므로 첫 번째 열 1의 출력이 가 됩니다 11+21+51+61+71+81+111. 그렇다면 407이 경우에도 숫자를 함께 추가하여 인쇄 하시겠습니까 ?

나는 단지 a()와 b()가 함수이고 어딘가에서 평가할 것이라고 가정합니다. 그렇지 않다면 모든 것을 awk.

답변2

누적할 행의 불규칙한 선택을 고려하면 보다 일반적인 해결책을 고안하기는 어려우며, 궁극적으로 다음과 같은 최적의 선택으로 이어집니다.

sed 's/row[0-9]*//;/^$/d' file | pr -2t -w 1000 | awk '
NR==1 {split($0,h);w=NF;c=".aabbaaaabbab";next;}
substr(c,NR,1)=="a" {for(i=1;i<=NF;i++)a[i]+=$i;next;}
{for(i=1;i<=NF;i++) b[i]+=$i;}
END {for(i=1;i<=w;i++)printf"%s %d %d\n",h[i],a[i],b[i];}'

최종 레이아웃도 에서 직접 생성됩니다 awk. 분명히 체리 따기는 다양한 방법으로 수행될 수 있습니다. 여기서는 "a" 및 "b" 문자열을 사용하여 어떤 행이 어떤 결과 열에 추가되는지 나타냈습니다.

9보다 큰 줄 번호를 수용하려면 초기 sed표현식을 약간 수정해야 합니다.

관련 정보