İki sütunun eşleşmesine göre iki dosya nasıl birleştirilir?


33

Ben dosya1 seviyor:

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

Ve bir dosya2:

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

Ve şöyle bir dosya3 istiyorum:

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

Bu, 2. sütunun 4. sütununun, 2. sütunun adıyla dosya1'e geçirilmesi anlamına gelir.


1
File2 sadece üç sütun var?
Bernhard

Yanıtlar:


48

Bu yapmalı:

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

Önemli : Bu, dosyalarınızın SNP adına göre (örneğinizde olduğu gibi) sıralandığını varsayar. Değilse, önce bunları sıralayın:

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

Çıktı:

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

Açıklama (den info join):

`join ', aynı birleştirme alanlarına sahip her girdi satırı çifti için standart çıktıya yazıyor.

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

Bu nedenle, yukarıdaki komut ikinci alandaki dosyaları birleştirir ve birinci dosyanın 1., 2. ve 3. alanlarını ve ardından 3. dosyanın alanını2 yazdırır.


16

Kullanabilirsiniz awk:

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

çıktı:

$ 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

Açıklama:

Yürüyün file2( NR==FNRsadece ilk dosya argümanı için geçerlidir). Sütun 3'ü, anahtar olarak sütun 2 kullanarak karma dizisinde saklayın h[$2] = $3. Sonra yürüyün file1ve her üç sütunun da çıktısını $1,$2,$3alın, karma diziden karşılık gelen kaydedilmiş sütunu ekleyin h[$2].


Çok teşekkürler. Merak ediyorum, 'h [2 $] = 3 $ ne demek? Aslında karmaşık durumlarda (aynı sırayla gerekli değildir) dosya1 $ 2 == dosya2 $ 2 ile tam olarak eşleşmem gerekiyor.
Dadong Zhang,

1
h[$2] = $3bir karma atamadır. Bu kurtarmak $3değer olarak ve $2anahtar olarak. Örnek: h["name"] = "Dadong". Şimdi print h["name"]çıktılar Dadong. İstediğinizi yapar, her iki dosyadan da ikinci sütuna tam olarak uyar.
grebneke

6

Herhangi bir siparişe ihtiyacınız yoksa, daha basit bir çözüm

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

Bu, tüm satırların üç girişe sahip olduğunu ve her iki dosyanın da 1. ve 2. sütunlarının aynı olduğunu varsayar (örnek verilerinizde olduğu gibi).


1
Büyük kullanım için +1paste
grebneke

1
@grebneke ve Bernhard, ne zamandan beri hayranları gibi görünüyor pastecevap için bir yol buluruz bu coreutils ile?
terdon

@terdon - mütevazi bir girişim: unix.stackexchange.com/a/113909/32165
grebneke

1
@terdon Bu s çıkacak programı yeniden gözden geçirmenizi tavsiye ederim ***
Bernhard

Biçimi ile yanlış bir şey yok, tamamen iyi sekme ayrılmış dosyaları. Her durumda, bu tür verilerle, genellikle format konusunda bir seçeneğiniz olmaz, başka bir programdan çıkar.
Terdon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.