Bagaimana cara menggabungkan dua file berdasarkan pencocokan dua kolom?


33

Saya punya suka file1:

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

Dan file2:

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

Dan ingin file3 sedemikian rupa sehingga:

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

Yang berarti menempatkan kolom ke-4 dari file2 ke file1 dengan nama kolom ke-2.


1
File2 hanya punya tiga kolom?
Bernhard

Jawaban:


48

Ini harus dilakukan:

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

Penting : ini mengasumsikan file Anda diurutkan (seperti dalam contoh Anda) sesuai dengan nama SNP. Jika tidak, urutkan terlebih dahulu:

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

Keluaran:

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

Penjelasan (dari info join):

`join 'menulis ke output standar sebuah garis untuk setiap pasangan jalur input yang memiliki bidang gabungan yang identik.

`-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.

Jadi, perintah di atas menggabungkan file-file di bidang kedua dan mencetak bidang 1, 2 dan 3 dari file satu, diikuti oleh bidang ke-3 dari file2.


16

Anda bisa menggunakan awk:

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

keluaran:

$ 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

Penjelasan:

Walk through file2( NR==FNRhanya berlaku untuk argumen file pertama). Kirimkan kolom 3 di hash-array menggunakan kolom 2 sebagai kunci: h[$2] = $3. Kemudian berjalan melalui file1dan output ketiga kolom $1,$2,$3, menambahkan kolom tersimpan yang sesuai dari hash-array h[$2].


Terima kasih banyak. Hanya ingin tahu, apa arti 'h [$ 2] = $ 3'? Sebenarnya saya harus mencocokkan persis file1 $ 2 == file2 $ 2 dalam kasus kompleks saya (yang tidak perlu dalam urutan yang sama).
Dadong Zhang

1
h[$2] = $3adalah tugas hash. Ini menyimpan $3sebagai nilai dan $2sebagai kunci. Contoh: h["name"] = "Dadong". Sekarang, print h["name"]keluaran Dadong. Itu tidak apa yang Anda inginkan, itu cocok persis kolom kedua dari kedua file.
grebneke

6

Jika Anda tidak memerlukan pemesanan apa pun, daripada solusi sederhana

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

Ini mengandaikan bahwa semua baris memiliki tiga entri, dan kolom 1 dan 2 dari kedua file adalah sama (seperti pada contoh data Anda)


1
+1 untuk penggunaan luar biasapaste
grebneke

1
@ grebneke dan Bernhard, karena Anda tampaknya penggemar, pastebisakah Anda mencari cara untuk menjawab ini dengan coreutils?
terdon

@terdon - upaya sederhana: unix.stackexchange.com/a/113909/32165
grebneke

1
@terdon, saya akan menyarankan untuk mempertimbangkan kembali program yang menghasilkan video ini
Bernhard

Tidak ada yang salah dengan formatnya, file tab yang dipisahkan dengan baik. Bagaimanapun, dengan jenis data ini Anda biasanya tidak punya pilihan untuk format, itu keluar dari program lain.
terdon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.