bien joindre deux fichiers basé sur 2 colonnes en commun
J'ai deux fichiers que je suis en train de jointure de fusion basés sur des colonnes 1
et 2
. Ils ressembler à quelque chose comme ça, avec file1
(58210
lignes) étant beaucoup plus courte que file2
(815530
lignes) et j'aimerais trouver l'intersection de ces deux fichiers sur la base des champs de 1
et 2
comme un indice:
file1
:
2L 25753 33158
2L 28813 33158
2L 31003 33158
2L 31077 33161
2L 31279 33161
3L 32124 45339
3L 33256 45339
...
file2
:
2L 20242 0.5 0.307692307692308
2L 22141 0.32258064516129 0.692307692307692
2L 24439 0.413793103448276 0.625
2L 24710 0.371428571428571 0.631578947368421
2L 25753 0.967741935483871 0.869565217391304
2L 28813 0.181818181818182 0.692307692307692
2L 31003 0.36 0.666666666666667
2L 31077 0.611111111111111 0.931034482758621
2L 31279 0.75 1
3L 32124 0.558823529411765 0.857142857142857
3L 33256 0.769230769230769 0.90625
...
J'ai été en utilisant le couple suivant de commandes, mais avec différents nombres de lignes:
awk 'FNR==NR{a[$1$2]=$3;next} {if($1$2 in a) print}' file1 file2 | wc -l
awk 'FNR==NR{a[$1$2]=$3;next} {if($1$2 in a) print}' file2 file1 | wc -l
Je ne suis pas sûr de savoir pourquoi cela se passe, et j'ai essayé de tri préalable à la comparaison, juste au cas où j'ai des lignes dupliquées (basés sur des colonnes 1
et 2
) dans les fichiers, mais il ne semble pas aider. (Pourquoi il en est ainsi sont aussi appréciés)
Comment puis-je fusionner les fichiers de façon à ce que les lignes de file2
qui ont les colonnes correspondantes 1
et 2
dans file1
imprimée, avec la colonne 3
de file1
ajouté, à ressembler à quelque chose comme ceci:
2L 25753 0.967741935483871 0.869565217391304 33158
2L 28813 0.181818181818182 0.692307692307692 33158
2L 31003 0.36 0.666666666666667 33158
2L 31077 0.611111111111111 0.931034482758621 33161
2L 31279 0.75 1 33161
3L 32124 0.558823529411765 0.857142857142857 45339
3L 33256 0.769230769230769 0.90625 45339
ce champ(s) doit être utilisé pour joindre les rangs?
Ou ils devraient être rejoints ligne par ligne?
Vos données de l'échantillon n'a pas de lignes de correspondance...
Vous devez avoir un fichier qui a été créé sur le DOS et un sur UNIX ou quelque chose comme il y a eu une sorte de caractères de contrôle à la fin des lignes dans un ou deux fichiers qui sont gâcher avec de la sortie. Essayez le "chat -v" sur les deux fichier pour voir les caractères de contrôle, et d'essayer dos2unix sur les deux à la corriger.
OriginalL'auteur suegene | 2012-10-21
Vous devez vous connecter pour publier un commentaire.
Look:
Si ce n'est pas ce que vous voulez, veuillez préciser et peut-être avec un peu plus d'un échantillon représentatif d'entrée/sortie.
Version commentée du code ci-dessus pour lui fournir des explications:
Espère que ça aide.
Vous avez raison, votre solution fonctionne. J'ai vérifié sur votre dossier que vous avez donné comme exemple. J'ai essayé de déposer le post ci-dessus. Désolé pour l'erreur.
voir modifiée la réponse ci-dessus.
J'ai appris de nombreuses astuces de vous. et cette réponse avec explication complète méritent
nice answer
badge! +1!Belle réponse! Bravo pour être 20K, entièrement mérité pour votre awk guru-ism 🙂
OriginalL'auteur
Si vous souhaitez rejoindre le fichiers ligne par ligne, puis utiliser cette commande:
Que vous avez mis à jour la question:
Tout d'abord remplacer le premier délimiteur dans chaque ligne avec un certain caractère non espace et triez les deux fichiers d'entrée. Ensuite, utilisez
join
pour effectuer le rejoindre. Filtre de sa sortie, afin de remplacer le non-espace de char avec de l'espace.C'est la sortie à partir des fichiers comme dans la question:
join
ne semble fonctionner avec une seule colonne.Je n'ai pas eu de réponse de l'OP sur mes questions, donc j'ai simplement supposé que la jointure à faire ligne par ligne, donc je ne la jointure sur la numérotation des lignes produites par chat
OK — juste assez; je ne pense pas que c'est ce que l'OP avait en tête, mais j'avais raté le
-n
sur lecat
commandes (mais puis-je m'abonner à la New Jersey à l'école pour la conception decat
et "cat
revint de Berkeley, agitant des drapeaux` (une paraphrase d'un devis adressé par Ken Thompson) m'agace).J'arrive même pas à comprendre pourquoi il n'est pas surpris d'obtenir une seule ligne de sortie à condition que les données et l'obligation d'adhérer sur les colonnes 1 & 2.
consultez la mise à jour alors
OriginalL'auteur
Vous pouvez utiliser le
join
de commande, mais vous avez besoin pour créer un seul champ de jointure dans chaque tableau de données. En supposant que vous avez des valeurs autres que2L
dans la colonne 1, ce code devrait fonctionner indépendamment de la triés ou non triées de la nature des deux fichiers d'entrée:Si vous avez
bash
et de processus de substitution", ou si vous savez que les données sont déjà triées de manière appropriée, vous pouvez simplifier le traitement.Je ne suis pas entièrement sûr de savoir pourquoi votre code ne fonctionnait pas, mais je serais probablement à l'aide de
a[$1,$2]
pour les indices; il vous donnera moins de problèmes si certains de vos la colonne 1, les valeurs sont de purs numérique et peut donc être confus quand vous concaténer les colonnes 1 et 2. C'est pourquoi la "création de la clé'awk
scripts utilisés une virgule entre les champs.Révision des fichiers de données comme indiqué:
fichier1
fichier2
(Inchangé par rapport à la question.)
De sortie
OriginalL'auteur