2016-08-19 3 views
1

J'ai trois fichiers séparés par des espaces.Joindre des colonnes en fonction de la valeur dans la première colonne mais sans que la colonne apparaisse deux fois

Fichier 1 (file1.txt):

FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 
A1 A1 0 1 1 2 
A2 A2 1 2 1 2 
A3 A3 0 1 1 1 

Fichier 2 (file2.txt):

FID Bw4 
A1 2 
A2 1 
A3 1 

fichier 3 (file3.txt):

FID IID INFO 
A1 A1 0.4 
A2 A2 0.6 
A3 A3 0.2 

Je veux fusionner les 3 fichiers dans un seul fichier si la valeur dans la colonne FID est le même entre les 3 fichiers, afin d'avoir:

FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 Bw4 INFO 
A1 A1 0 1 1 2 2 0.4 
A2 A2 1 2 1 2 1 0.6 
A3 A3 0 1 1 1 1 0.2 

Je sais que je peux fusionner les fichiers en utilisant la commande suivante :

join file1.txt file2.txt | join - file3.txt > final.txt 

Mais en utilisant cette commande, il ajoute également la colonne IID du dossier 3, apparaissant ainsi deux fois, comme ceci:

FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 Bw4 IID INFO 
A1 A1 0 1 1 2 2 A1 0.4 
A2 A2 1 2 1 2 1 A1 0.6 
A3 A3 0 1 1 1 1 A1 0.2 

est-il un moyen de rejoindre les 3 fichiers sans avoir cette colonne deux fois?

Informations importantes:

  • Tous les FIDs sont en commun entre les 3 fichiers.

  • Le nombre de colonnes présentes dans 1 fichier peut changer

+0

Le nombre de colonnes dans file3 est-il statique? Si oui, vous pouvez supprimer la deuxième colonne de file3 (voir 'man colrm'). En utilisant bash [substitution de processus] (http://tldp.org/LDP/abs/html/process-sub.html): 'join file1.txt file2.txt | join - <(colrm 2

+0

" Je sais que je peux fusionner les fichiers en utilisant awk comme ceci: "?? Aucun code awk montré ;-) Bonne chance! – shellter

Répondre

0

Essayez this-

paste file1.txt file2.txt file3.txt | awk '{ if ($1==$7 && $1==$9) print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t" $8 "\t" $11}' 

Explanation-

pâte met les fichiers l'un après l'autre.

awk '{if()}' vérifie que la condition est vraie.

Le repos n'est que cosmétique.

+0

Cela ne fonctionne pas non plus si le nombre de colonnes dans le fichier 1 change. –

0

essayez ceci;

join file1.txt file2.txt | join - file3.txt | awk -v OFS=' ' 'NR==1{for (i=1;i<=NF;i++)if ($i=="IID"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' | column -t 

Ceci est votre code;

join file1.txt file2.txt | join - file3.txt 

Pour une mise en forme élégante;

column -t 

pour supprimer la colonne IID avec awk;

awk -v OFS='\t' 'NR==1{for (i=1;i<=NF;i++)if ($i=="IID"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' 

ex:

[email protected]:/tmp/1$ join file1.txt file2.txt | join - file3.txt | awk -v OFS=' ' 'NR==1{for (i=1;i<=NF;i++)if ($i=="IID"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' | column -t 
FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 Bw4 INFO 
A1 A1 0 1   1  2  2 0.4 
A2 A2 1 2   1  2  1 0.6 
A3 A3 0 1   1  1  1 0.2 
+0

Cela ne fonctionne pas si le nombre de colonnes a changé dans file1. Ensuite, ce ne serait plus la 8ème colonne. –

+0

@MartinNyolt J'ai mis à jour ans. peut-être que vous pouvez l'utiliser; –

0

Vous pouvez utiliser la substitution cut et un processus pour retirer la deuxième colonne du fichier 3 avant de rejoindre:

$ join file1.txt file2.txt | join - <(cut --complement -d ' ' -f 2 file3.txt) 
FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 Bw4 INFO 
A1 A1 0 1 1 2 2 0.4 
A2 A2 1 2 1 2 1 0.6 
A3 A3 0 1 1 1 1 0.2 

--complement est une extension GNU. Si vous ne pouvez pas l'utiliser, l'alternative est

join file1.txt file2.txt | join - <(cut -d ' ' -f 1,3 file3.txt)