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.