Joignez deux fichiers avec des colonnes correspondantes

11

File1.txt

    id                            No
    gi|371443199|gb|JH556661.1| 7907290
    gi|371443198|gb|JH556662.1| 7573913
    gi|371443197|gb|JH556663.1| 7384412
    gi|371440577|gb|JH559283.1| 6931777

File2.txt

 id                              P       R       S
 gi|367088741|gb|AGAJ01056324.1| 5       5       0
 gi|371443198|gb|JH556662.1|     2       2       0
 gi|367090281|gb|AGAJ01054784.1| 4       4       0
 gi|371440577|gb|JH559283.1|     21      19      2

output.txt

 id                              P       R       S  NO
 gi|371443198|gb|JH556662.1|     2       2       0  7573913
 gi|371440577|gb|JH559283.1|     21      19      2  6931777

File1.txt a deux colonnes et File2.txt a quatre colonnes. Je veux joindre les deux fichiers qui ont un identifiant unique (le tableau [1] doit correspondre dans les deux fichiers (file1.txt et file2.txt) et ne donner à l'output que l'identifiant correspondant (voir output.txt).

J'ai essayé join -v <(sort file1.txt) <(sort file2.txt). Toute aide avec les commandes awk ou join demandée.

jack
la source

Réponses:

18

join fonctionne très bien:

$ join <(sort File1.txt) <(sort File2.txt) | column -t | tac
 id                           No       P   R   S
 gi|371443198|gb|JH556662.1|  7573913  2   2   0
 gi|371440577|gb|JH559283.1|  6931777  21  19  2

ps. l'ordre des colonnes de sortie est-il important?

si oui, utilisez:

$ join <(sort 1) <(sort 2) | tac | awk '{print $1,$3,$4,$5,$2}' | column -t
 id                           P   R   S  No
 gi|371443198|gb|JH556662.1|  2   2   0  7573913
 gi|371440577|gb|JH559283.1|  21  19  2  6931777
se ruer
la source
fonctionne très bien. l'ordre des colonnes n'a pas d'importance
jack
Quelle est la raison de l'inclusion tac?
Michael Mrozek
C'est parce que sortplace la chaîne d'en-tête à la fin. En fait, c'est une sale solution. Et dans le cas général, l'en-tête peut aller au milieu de la sortie. Cependant, cela fonctionne ici.
rush
10

À sens unique en utilisant awk:

Contenu de script.awk:

## Process first file of arguments. Save 'id' as key and 'No' as value
## of a hash.
FNR == NR {
    if ( FNR == 1 ) { 
        header = $2
        next
    }   
    hash[ $1 ] = $2
    next
}

## Process second file of arguments. Print header in first line and for
## the rest check if first field is found in the hash.
FNR < NR {
    if ( $1 in hash || FNR == 1 ) { 
        printf "%s %s\n", $0, ( FNR == 1 ? header : hash[ $1 ] ) 
    }   
}

Exécutez-le comme:

awk -f script.awk File1.txt File2.txt | column -t

Avec le résultat suivant:

id                           P   R   S  NO
gi|371443198|gb|JH556662.1|  2   2   0  7573913
gi|371440577|gb|JH559283.1|  21  19  2  6931777
Birei
la source
+65535 pour conserver l'ordre de ligne d'origine. :-)
zeekvfu
+65535 pour conserver l'ordre de ligne d'origine. :-)
zeekvfu