일치하는 줄을 한 줄로 병합

일치하는 줄을 한 줄로 병합

awk중복된 줄을 찾아 하나로 병합하라는 명령이 멈췄습니다.

내 파일은 다음과 같습니다(헤더가 없음). 이미 2열에 정렬되어 있습니다.

1, abc, 123, , , , , , , , , ,
2, xyz, 123, , , , , , , , , ,
3, pqr, 123, , , , , , , , , ,
4, pqr, 123, , ,10, ,12, , , , ,
5, pqr, 123, , , , , , , ,1,2,
6, def, 123, , , , , , , , , ,
7, lmn, 123, , , , , , , , , ,
8, lmn, 123, , ,22, ,11, , , , ,
9, tuv, 123, , , , , , , , , ,
10, qrs, 123, , , , , , , , , ,

출력은 다음과 같습니다:

1, abc, 123, , , , , , , , , ,
2, xyz, 123, , , , , , , , , ,
3, pqr, 123, , ,10, ,12, , ,1,2,
6, def, 123, , , , , , , , , ,
7, lmn, 123, , , 22, 11, , , , , ,
9, tuv, 123, , , , , , , , , ,
10, qrs, 123, , , , , , , , , ,

도움을 주시면 감사하겠습니다. 미리 감사드립니다

답변1

이 작업은 한 줄의 코드로 수행할 수 있지만 전체 스크립트를 작성할 만큼 까다롭습니다.

#!/usr/bin/awk -f
# This shebang works on Mac; Linux boxes should use:
#!/bin/awk -f

BEGIN {
  FS = ", *";
  OFS = ", "
}

function printhold() {
  for (i=1; i<size; i++) {
    printf "%s", hold[i] OFS
  }
  print hold[size]
}

NR == 1 {
  size = split ($0, hold, ", *")
  next
}

hold[2] == $2 {
  for (i=4; i<=size; i++) {
    if (hold[i] == "") {
      hold[i] = $i
    }
  }
  next
}

{
  printhold()
  size = split ($0, hold, ", *")
} 

END {
  printhold()
}

높은 수준에서 수행되는 작업은 다음과 같습니다.

  1. 한 줄씩 기억해 두세요. (인쇄하지 마세요.)
  2. 다음 줄을보세요. 필드 2가 예약된 라인의 필드 2와 일치하는 경우:
  3. 행을 보유하는 각 필드에 대해 필드가 비어 있으면 현재 보고 있는 행의 해당 필드 값으로 설정됩니다.
  4. 2로 가세요.
  5. 현재 줄의 필드 2아니요예약된 필드 2와 일치합니다(즉, 2단계의 테스트가 실패함).
  6. 예약된 라인 인쇄
  7. 메모리에 있는 줄을 다음 줄(위의 5에서 찾은 일치하지 않는 줄)로 바꿉니다.
  8. 2로 가세요.
  9. 파일 끝에 도달하면 나머지 줄을 인쇄합니다.

위 코드 논리의 핵심 부분(실제로 행을 병합하는 부분)은 다음과 같습니다.

hold[2] == $2 {
  for (i=4; i<=size; i++) {
    if (hold[i] == "") {
      hold[i] = $i
    }
  }
  next
}

이는 개략적인 설명의 2~4단계와 일치합니다.

관련 정보