web-dev-qa-db-fra.com

Comment fusionner deux fichiers en fonction de la correspondance de deux colonnes?

J'ai file1 aime:

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

Et un fichier2:

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

Et voudrait un fichier3 tel que:

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

Ce qui signifie mettre la 4ème colonne de fichier2 en fichier1 par le nom de la 2ème colonne.

32
Dadong Zhang

Cela devrait le faire:

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

Important: cela suppose que vos fichiers sont triés (comme dans votre exemple) selon le nom SNP. Si ce n'est pas le cas, triez-les d'abord:

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

Production:

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

Explication (de info join):

`join 'écrit sur la sortie standard une ligne pour chaque paire de lignes d'entrée qui ont des champs de jointure identiques.

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

Ainsi, la commande ci-dessus joint les fichiers sur le deuxième champ et imprime les 1er, 2e et 3e champs du fichier un, suivi du 3e champ du fichier2.

49
terdon

Vous pouvez utiliser awk:

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

production:

$ 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

Explication:

Procédure pas à pas file2 (NR==FNR n'est vrai que pour le premier argument de fichier). Enregistrez la colonne 3 dans le tableau de hachage en utilisant la colonne 2 comme clé: h[$2] = $3. Parcourez ensuite file1 et afficher les trois colonnes $1,$2,$3, en ajoutant la colonne enregistrée correspondante du tableau de hachage h[$2].

17
grebneke

Si vous n'avez besoin d'aucune commande, une solution simple serait

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

Cela suppose que toutes les lignes ont trois entrées et que les colonnes 1 et 2 des deux fichiers sont identiques (comme dans vos données d'exemple)

6
Bernhard