두 열의 일치를 기반으로 두 파일을 병합하는 방법은 무엇입니까?


33

나는 file1을 좋아한다.

0   AFFX-SNP-000541  NA
0   AFFX-SNP-002255  NA
1   rs12103          0.6401
1   rs12103_1247494  0.696
1   rs12142199       0.7672

그리고 file2 :

0   AFFX-SNP-000541   1
0   AFFX-SNP-002255   1
1   rs12103           0.5596
1   rs12103_1247494   0.5581
1   rs12142199        0.4931

그리고 file3을 다음과 같이 원합니다.

0   AFFX-SNP-000541     NA       1
0   AFFX-SNP-002255     NA       1
1   rs12103             0.6401   0.5596
1   rs12103_1247494     0.696    0.5581
1   rs12142199          0.7672   0.4931

이것은 두 번째 열의 이름으로 file2의 네 번째 열을 file1에 넣는 것을 의미합니다.


1
File2에 세 개의 열만 있습니까?
Bernhard

답변:


48

이것은해야합니다 :

join -j 2 -o 1.1,1.2,1.3,2.3 file1 file2

중요 : 파일이 SNP 이름에 따라 정렬되어 있다고 가정합니다. 그렇지 않은 경우 먼저 정렬하십시오.

join -j 2 -o 1.1,1.2,1.3,2.3 <(sort -k2 file1) <(sort -k2 file2)

산출:

0 AFFX-SNP-000541 NA 1
0 AFFX-SNP-002255 NA 1
1 rs12103 0.6401 0.5596
1 rs12103_1247494 0.696 0.5581
1 rs12142199 0.7672 0.4931

설명 (에서 info join) :

`join '은 동일한 결합 필드를 갖는 각 입력 라인 쌍에 대한 라인을 표준 출력에 기록합니다.

`-1 FIELD'
     Join on field FIELD (a positive integer) of file 1.

`-2 FIELD'
     Join on field FIELD (a positive integer) of file 2.

`-j FIELD'
     Equivalent to `-1 FIELD -2 FIELD'.

`-o FIELD-LIST'

 Otherwise, construct each output line according to the format in
 FIELD-LIST.  Each element in FIELD-LIST is either the single
 character `0' or has the form M.N where the file number, M, is `1'
 or `2' and N is a positive field number.

따라서 위의 명령은 두 번째 필드의 파일을 결합하고 파일 1의 첫 번째, 두 번째 및 세 번째 필드를 인쇄 한 다음 file2의 세 번째 필드를 인쇄합니다.


16

당신은 사용할 수 있습니다 awk:

$ awk 'NR==FNR {h[$2] = $3; next} {print $1,$2,$3,h[$2]}' file2 file1 > file3

산출:

$ cat file3
0 AFFX-SNP-000541 NA 1
0 AFFX-SNP-002255 NA 1
1 rs12103 0.6401 0.5596
1 rs12103_1247494 0.696 0.5581
1 rs12142199 0.7672 0.4931

설명:

안내합니다 file2( NR==FNR첫 번째 파일 인수에 대해서만 참). 열 2를 키로 사용하여 열 3을 해시 배열에 저장하십시오 h[$2] = $3. 그런 다음 해시 배열에서 해당 저장된 열을 추가하여 file1세 열을 모두 걷고 출력하십시오 .$1,$2,$3h[$2]


고마워 'h [$ 2] = $ 3'이 무슨 뜻입니까? 실제로 복잡한 경우에는 file1 $ 2 == file2 $ 2와 정확히 일치해야합니다 (동일한 순서는 필요하지 않음).
Dadong Zhang

1
h[$2] = $3해시 할당입니다. $3값과 $2키로 저장 됩니다 . 예 : h["name"] = "Dadong". 이제 print h["name"]출력 Dadong합니다. 원하는 것을 수행하며 두 파일의 두 번째 열과 정확히 일치합니다.
grebneke

6

주문이 필요하지 않은 경우 간단한 솔루션보다

paste file{1,2} | awk '{print $1,$2,$3,$6}' > file3

이것은 모든 행에 세 개의 항목이 있고 두 파일의 열 1과 2가 동일하다고 가정합니다 (예제 데이터에서와 같이)


1
–1 사용paste
grebneke

1
@grebneke와 Bernhard, 당신은 팬인 것 같아서 coreutils로 이것paste 에 대답하는 방법을 알아낼 수 있습니까?
terdon

@terdon-겸손한 시도 : unix.stackexchange.com/a/113909/32165
grebneke

1
@ terdon 나는이 s를 출력하는 프로그램을 재고하는 것이
Bernhard

형식에 문제가 없으며 탭으로 구분 된 파일이 완벽합니다. 어쨌든 이러한 종류의 데이터를 사용하면 일반적으로 형식을 선택할 수 없으며 다른 프로그램에서 나옵니다.
terdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.