이렇게 두 테이블을 병합하고 싶습니다
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
스크립트의 마지막 줄은awk
awk의 관용적 약어 입니다{print}
. 값은1
true로 평가되고 일부 값이 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