두 개의 공통 열을 기반으로 두 개의 테이블을 조인하고 일치하지 않는 경우 NA 또는 Null 값을 추가합니다.

두 개의 공통 열을 기반으로 두 개의 테이블을 조인하고 일치하지 않는 경우 NA 또는 Null 값을 추가합니다.

이렇게 두 테이블을 병합하고 싶습니다

1 번 테이블

Chr1 5
Chr1 10
Chr1 20
Chr2 10
Chr2 30

표 2

Chr1 10 value value2
Chr1 20 value value2
Chr2 30 value value2

원하는 출력

Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2

두 테이블의 두 열과 일치하는 행만 유지하는 테이블 병합을 위해 awk에서 스크립트를 찾았습니다. 하지만 여기서는 Table_1의 모든 행을 원하지만 일치하는 경우 Table_2의 값을 추가합니다. 이것을 달성하는 방법을 말해 줄 수 있습니까?

답변1

$ awk '{ key = $1 FS $2 };
       NR == FNR { t[key] = $0; next };
       key in t { print t[key]; next };
       1' table2.txt table1.txt
Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2
  • 읽은 각 입력 행에서(읽은 두 파일 모두에 대해) 변수는 key처음 두 필드( $1$2)로 설정되며 그 사이에는 필드 구분 기호( FS)가 있습니다. FS두 필드 모두에 포함되지 않는 것이 보장되는 유일한 문자이므로 고유 키를 생성하는 것이 보장되는 유일한 문자이기 때문에 사용됩니다. 키는 라는 연관 배열에 대한 인덱스로 사용됩니다 t.

  • table2.txt읽을 때 (~ 해야 하다명령줄의 첫 번째 파일 이름 인수로 나열됨), 각 입력 줄은 배열의 한 요소에 저장됩니다 t.

    중복된 항목이 포함된 경우 에만 기억됩니다 table2.txt. 즉, 처음 두 필드가 동일한 여러 행이 있는 경우입니다.마지막하나는 본다. 이러한 모든 중복 항목(나타나는 순서대로)을 기억하려면 awk 스크립트의 두 번째 줄을 다음과 같이 변경하세요.

     NR == FNR { if (key in t) { t[key] = t[key] "\n" $0 } else { t[key] = $0 }; next };
    
  • 첫 번째 파일 읽기가 끝나면 table1.txt(두 번째 파일 이름 arg)을 읽고 배열에 해당 항목이 table2있으면 인쇄하고, 그렇지 않으면 현재 줄을 인쇄합니다.

  • 1스크립트의 마지막 줄은 awkawk의 관용적 약어 입니다 {print}. 값은 1true로 평가되고 일부 값이 true로 평가되면 기본 작업은 현재 줄을 인쇄하는 것입니다.

참고: table2.txt용량이 크면 RAM을 많이 사용하게 됩니다. 이는 기가바이트 RAM을 갖춘 최신 시스템에서는 문제가 되지 않을 것입니다.

답변2

$ awk '{k=$1 FS $2} NR==FNR{map[k]=$0; next} {print (k in map ? map[k] : $0)}' table2 table1
Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2

관련 정보