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