Comment utiliser la commande join sous Linux



Si vous désirez combiner des données issues de deux fichiers texte en les reliant par un élément commun, la commande « join » de Linux est l’outil idéal. Elle apporte une dimension dynamique à vos fichiers de données statiques. Cet article vous explique comment l’utiliser efficacement.

Lier des données entre différents fichiers

Les données sont essentielles. Les entreprises, les organisations et même les particuliers dépendent de leur manipulation. Cependant, jongler avec des données dispersées dans divers fichiers, souvent créés par différentes personnes, peut s’avérer complexe. Il ne s’agit pas seulement de savoir quels fichiers ouvrir pour trouver l’information, mais aussi de gérer les différences de mise en page et de format.

De plus, se pose la problématique de la gestion administrative : quels fichiers doivent être mis à jour, sauvegardés, archivés, et quels sont ceux qui sont devenus obsolètes.

Si vous avez besoin de fusionner vos données ou d’effectuer une analyse sur un ensemble complet, le défi est encore plus grand. Comment uniformiser ces informations disséminées avant de pouvoir les utiliser ? Comment abordez-vous la phase de préparation des données ?

Heureusement, si les fichiers partagent au moins un champ de données commun, la commande « join » de Linux peut vous simplifier grandement la tâche.

Les fichiers de données utilisés

Pour illustrer le fonctionnement de la commande « join », nous allons utiliser des données fictives, à partir des deux fichiers suivants :

cat file-1.txt
cat file-2.txt

Voici le contenu de « file-1.txt » :

1 Adore Varian avarian0@newyorker.com Female 192.57.150.231
2 Nancee Merrell nmerrell1@ted.com Female 22.198.121.181
3 Herta Friett hfriett2@dagondesign.com Female 33.167.32.89
4 Torie Venmore tvenmore3@gmpg.org Female 251.9.204.115
5 Deni Sealeaf dsealeaf4@nps.gov Female 210.53.81.212
6 Fidel Bezley fbezley5@lulu.com Male 72.173.218.75
7 Ulrikaumeko Standen ustanden6@geocities.jp Female 4.204.0.237
8 Odell Jursch ojursch7@utexas.edu Male 1.138.85.117

Ce fichier contient des lignes numérotées, chacune incluant les informations suivantes :

Un numéro
Un prénom
Un nom de famille
Une adresse e-mail
Le sexe de la personne
Une adresse IP

Voici maintenant le contenu de « file-2.txt » :

1 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
6 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Standen ustanden6@geocities.jp Female Capital District $674,634.93
8 Jursch ojursch7@utexas.edu Male Hudson Valley $663,821.09

Chaque ligne de « file-2.txt » contient les informations suivantes :

Un numéro
Un nom de famille
Une adresse e-mail
Le sexe de la personne
Une région de New York
Une valeur monétaire

La commande « join » fonctionne en utilisant des « champs ». Dans ce contexte, un champ est une portion de texte délimitée par des espaces, le début d’une ligne ou la fin d’une ligne. Pour que « join » puisse associer les lignes entre deux fichiers, chaque ligne doit contenir un champ commun.

Nous ne pouvons donc faire correspondre que les champs présents dans les deux fichiers. L’adresse IP n’apparaissant que dans un seul fichier, elle ne convient pas. De même, le prénom n’apparaît que dans un seul fichier. Le nom de famille est présent dans les deux, mais ce serait un mauvais choix, car plusieurs personnes peuvent partager le même nom.

De même, on ne peut pas utiliser le champ « sexe » car il est trop générique. Les régions de New York et les valeurs monétaires sont uniques à un seul fichier.

Cependant, l’adresse e-mail est présente dans les deux fichiers et est unique pour chaque personne. En examinant les fichiers, on constate que les lignes correspondantes concernent la même personne. On peut aussi utiliser les numéros de ligne comme champ de correspondance (nous utiliserons un champ différent plus tard).

Il est important de noter que les deux fichiers n’ont pas le même nombre de champs, ce qui n’est pas un problème. Nous pouvons spécifier à « join » quel champ utiliser dans chaque fichier.

Faites attention aux champs comme les régions de New York : dans un fichier délimité par des espaces, chaque mot du nom d’une région ressemble à un champ. Certaines régions ayant des noms composés de plusieurs mots, cela peut créer un nombre variable de champs dans le même fichier. Ceci n’est pas un problème tant que vous faites correspondre les champs qui précèdent les régions de New York dans la ligne.

Utilisation de la commande join

Tout d’abord, le champ utilisé pour la correspondance doit être trié. Dans nos fichiers, les numéros sont croissants, ce qui répond à ce critère. Par défaut, « join » utilise le premier champ, ce qui est notre cas. De plus, « join » s’attend à ce que les champs soient délimités par des espaces, ce qui est également vrai pour nos fichiers. Nous pouvons donc procéder à la jointure.

Comme nous utilisons toutes les valeurs par défaut, notre commande est très simple :

join file-1.txt file-2.txt

« join » considère que les fichiers sont « fichier un » et « fichier deux » selon leur ordre d’apparition sur la ligne de commande.

Voici le résultat de cette commande :

1 Adore Varian avarian0@newyorker.com Female 192.57.150.231 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Nancee Merrell nmerrell1@ted.com Female 22.198.121.181 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Herta Friett hfriett2@dagondesign.com Female 33.167.32.89 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Torie Venmore tvenmore3@gmpg.org Female 251.9.204.115 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Deni Sealeaf dsealeaf4@nps.gov Female 210.53.81.212 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
6 Fidel Bezley fbezley5@lulu.com Male 72.173.218.75 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Ulrikaumeko Standen ustanden6@geocities.jp Female 4.204.0.237 Standen ustanden6@geocities.jp Female Capital District $674,634.93
8 Odell Jursch ojursch7@utexas.edu Male 1.138.85.117 Jursch ojursch7@utexas.edu Male Hudson Valley $663,821.09

Le résultat est formaté comme suit : le champ utilisé pour la correspondance est affiché en premier, suivi des autres champs du fichier un, puis des champs du fichier deux, sans le champ de correspondance.

Gestion des champs non triés

Essayons maintenant une opération qui ne fonctionnera pas. Nous allons désordonner les lignes d’un fichier afin que « join » ne puisse pas le traiter correctement. « file-3.txt » a le même contenu que « file-2.txt », mais la ligne huit est placée entre les lignes cinq et six.

Voici le contenu de « file-3.txt » :

1 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
8 Jursch ojursch7@utexas.edu Male Hudson Valley $663,821.09
6 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Standen ustanden6@geocities.jp Female Capital District $674,634.93

Nous lançons la commande suivante pour tenter de joindre « file-3.txt » avec « file-1.txt » :

join file-1.txt file-3.txt

« join » signale que la septième ligne de « file-3.txt » est mal triée et qu’elle n’est donc pas traitée. La ligne sept est celle qui commence par le numéro six, qui doit venir avant huit dans une liste correctement triée. La sixième ligne du fichier (qui commence par « 8 Odell ») a été la dernière traitée, c’est pour cela que l’on voit sa sortie.

Vous pouvez utiliser l’option « –check-order » si vous souhaitez vérifier si « join » est satisfait de l’ordre de tri d’un fichier, sans tenter de fusion.

Pour cela, on tape la commande suivante :

join --check-order file-1.txt file-3.txt

« join » vous indique à l’avance qu’il y aura un problème avec la ligne sept du fichier « file-3.txt ».

Fichiers avec des lignes manquantes

Dans « file-4.txt », la dernière ligne a été supprimée. Il n’y a donc pas de ligne huit. Voici son contenu :

1 Varian avarian0@newyorker.com Female Western New York $535,304.73
2 Merrell nmerrell1@ted.com Female Finger Lakes $309,033.10
3 Friett hfriett2@dagondesign.com Female Southern Tier $461,664.44
4 Venmore tvenmore3@gmpg.org Female Central New York $175,818.02
5 Sealeaf dsealeaf4@nps.gov Female North Country $126,690.15
6 Bezley fbezley5@lulu.com Male Mohawk Valley $366,733.78
7 Standen ustanden6@geocities.jp Female Capital District $674,634.93

Nous tapons la commande suivante, et étonnamment, « join » ne se plaint pas et traite toutes les lignes qu’il peut :

join file-1.txt file-4.txt

La sortie affiche sept lignes fusionnées.

L’option « -a » (afficher les lignes non appariées) indique à « join » d’afficher également les lignes qui ne peuvent pas être mises en correspondance.

Ici, nous tapons la commande suivante pour indiquer à « join » d’afficher les lignes du fichier un qui ne peuvent pas être mises en correspondance avec les lignes du fichier deux :

join -a 1 file-1.txt file-4.txt

Sept lignes correspondent, et la huitième ligne du fichier un est affichée sans correspondance. Il n’y a pas d’informations fusionnées car « file-4.txt » ne contenait pas de ligne huit pour la mise en correspondance. Au moins, elle est visible dans la sortie, vous savez donc qu’il n’y a pas de correspondance dans « file-4.txt ».

Nous utilisons l’option « -v » (supprimer les lignes jointes) suivante pour afficher les lignes qui n’ont pas de correspondance :

join -v file-1.txt file-4.txt

On constate que la ligne huit est la seule qui n’a pas de correspondance dans le fichier deux.

Correspondance avec d’autres champs

Associons deux nouveaux fichiers en utilisant un champ autre que celui par défaut (champ un). Voici le contenu de « file-7.txt » :

avarian0@newyorker.com Female 192.57.150.231
dsealeaf4@nps.gov Female 210.53.81.212
fbezley5@lulu.com Male 72.173.218.75
hfriett2@dagondesign.com Female 33.167.32.89
nmerrell1@ted.com Female 22.198.121.181
ojursch7@utexas.edu Male 1.138.85.117
tvenmore3@gmpg.org Female 251.9.204.115
ustanden6@geocities.jp Female 4.204.0.237

Et voici le contenu de « file-8.txt » :

Female avarian0@newyorker.com Western New York $535,304.73
Female dsealeaf4@nps.gov North Country $126,690.15
Male fbezley5@lulu.com Mohawk Valley $366,733.78
Female hfriett2@dagondesign.com Southern Tier $461,664.44
Female nmerrell1@ted.com Finger Lakes $309,033.10
Male ojursch7@utexas.edu Hudson Valley $663,821.09
Female tvenmore3@gmpg.org Central New York $175,818.02
Female ustanden6@geocities.jp Capital District $674,634.93

Le seul champ pertinent à utiliser pour la jointure est l’adresse e-mail, qui est le champ un dans le premier fichier et le champ deux dans le second. Pour prendre cela en compte, on peut utiliser les options « -1 » (champ du fichier un) et « -2 » (champ du fichier deux), suivies d’un numéro indiquant le champ à utiliser pour la jointure dans chaque fichier.

Nous tapons la commande suivante pour indiquer à « join » d’utiliser le premier champ du fichier un et le second du fichier deux :

join -1 1 -2 2 file-7.txt file-8.txt

Les fichiers sont liés en utilisant l’adresse e-mail, qui apparaît comme premier champ dans chaque ligne du résultat.

Utiliser des séparateurs de champ différents

Que faire si vos fichiers ont des champs séparés par autre chose que des espaces ?

Les deux fichiers suivants sont délimités par des virgules. Le seul espace se trouve entre les mots des noms de lieux composés de plusieurs termes :

cat file-5.txt
cat file-6.txt

Nous pouvons utiliser l’option « -t » (caractère de séparation) pour spécifier à « join » quel caractère utiliser comme délimiteur de champ. Dans ce cas, il s’agit de la virgule. Nous tapons donc la commande suivante :

join -t, file-5.txt file-6.txt

Toutes les lignes sont mises en correspondance, et les espaces sont conservés dans les noms de lieux.

Ignorer la casse des lettres

Un autre fichier, « file-9.txt », est presque identique à « file-8.txt ». La seule différence est que certaines adresses e-mail contiennent une lettre majuscule, comme indiqué ci-dessous :

Female avarian0@newyorker.com Western New York $535,304.73
Female dsealeaf4@nps.gov North Country $126,690.15
Male Fbezley5@lulu.com Mohawk Valley $366,733.78
Female hfriett2@dagondesign.com Southern Tier $461,664.44
Female nmerrell1@ted.com Finger Lakes $309,033.10
Male Ojursch7@utexas.edu Hudson Valley $663,821.09
Female tvenmore3@gmpg.org Central New York $175,818.02
Female ustanden6@geocities.jp Capital District $674,634.93

Lorsque nous avons joint « file-7.txt » et « file-8.txt », cela fonctionnait parfaitement. Voyons ce qu’il se passe avec « file-7.txt » et « file-9.txt ».

Nous tapons la commande suivante :

join -1 1 -2 2 file-7.txt file-9.txt

Seules six lignes ont été mises en correspondance. Les différences entre les lettres majuscules et minuscules ont empêché les deux autres adresses e-mail d’être jointes.

Cependant, nous pouvons utiliser l’option « -i » (ignorer la casse) pour forcer la jointure à ignorer ces différences et à mettre en correspondance les champs qui contiennent le même texte, quelle que soit la casse.

Nous tapons la commande suivante :

join -1 1 -2 2 -i file-7.txt file-9.txt

Les huit lignes sont mises en correspondance et jointes avec succès.

Mélanger et adapter

La commande « join » est un outil puissant pour la préparation de données complexe. Vous pourriez avoir besoin d’analyser ces données, ou de les mettre en forme pour les importer dans un autre système.

Quelle que soit la situation, vous serez heureux d’avoir « join » dans votre arsenal !