동일한 키로 열 범위 결합

동일한 키로 열 범위 결합
Input file tab separated:
A   |B   |  C | KEY  |  D|  E|  F  |G     | H | I | J   |   k |      
----|----|----|------|---|---|-----|------|---|---|-----|-----|      
word|word|word| one  |  8|  8|qw123| ""   | ""| ""| word| word|      
word|word|word| one  |  8|  8|qw234| ""   | ""| ""| word| word|      
word|word|word| one  |  8|  8|qw111| er432| ""| ""| word| word|      
word|word|word| seven|  8|  8|tr123| ""   | ""| ""| word| word|      
word|word|word| seven|  8|  8|ww000| ""   | ""| ""| word| word|      


Desired Output:                                                                     
A   |B   |  C | KEY  |D |E |F    |G    |H    |I    |J   |K   |  
----|----|----|------|--|--|-----|-----|-----|-----|----|----|
word|word|word|one   | 8| 8|qw123|qw234|qw111|er432|word|word|
word|word|word|one   | 8| 8|qw123|qw234|qw111|er432|word|word|
word|word|word|one   | 8| 8|qw123|qw234|qw111|er432|word|word|
word|word|word|seven | 8| 8|tr123|ww000|""   |""   |word|word|
word|word|word|seven | 8| 8|tr123|ww000|""   |""   |word|word|

[F~I] 열 범위를 동일한 KEY로 병합합니다. 배열을 사용하지 않고 AWK에서 이를 달성할 수 있습니까? 키 열의 값이 변경되는 시점을 제어하는 ​​방법은 무엇입니까?

답변1

배열을 사용하지 않고 Awk에서 이 작업을 수행하는 방법을 이해할 수 없습니다. 배열 요소가 배열이 되도록 허용하는 Gawk에서 더 편리하지만 다차원 배열을 에뮬레이트하기 위해 일반 Awk를 사용하는 것도 쉽습니다.

기본적으로 입력 행을 기억한 다음 키가 변경되면 이를 출력(업데이트된 FI 필드와 함께)해야 합니다. 파일 끝에서도 이 작업을 수행해야 합니다. 편의상 출력 함수는 필연적으로 두 곳에서 호출되므로 사용합니다.

다음은 고정 열 번호를 사용합니다. 1-6과 11-12는 표준 데이터 필드이고, 4는 키 필드이고, 7-10은 ​​병합 필드입니다. 더 나은 이름이 필요하기 때문에 레이블이라고 부르겠습니다. 이것은 좋은 스타일이 아니며 일부 변수로 나누어야 할 수도 있습니다.

awk -F '\t' '
  function show_and_reset(            i, c) {
    for (i = 1; i <= count; ++i) {
      for (c = 1; c <= 6; ++c) printf "%s\t", data[i,c]
      for (f in tags) printf "%s\t", f;
      for (c = ntags; c <= 3; ++c) printf "\t" 
      for (c = 11; c <= 12; ++c) printf "\t%s", data[i,c]
      print ""
    }
    /* Clear the holding data */
    for (f in tags) delete tags[f]
    ntags = 0;
    count = 0
  }
  /* Record one line of data */
  function record(                   c) {
    ++count;
    for (c = 1; c <= 6; ++c) data[count,c] = $c
    for (c = 11; c <= 12; ++c) data[count,c] = $c
    for (c = 6; c <= 10; ++c) 
      if ($c != "" && !tags[$c]++) ++ntags;
  }
  $4 != key { show_and_reset(); key = $4; }
            { record(); }
  END       { show_and_reset(); }
'

관련 정보