Linux / Commande join : réunir deux fichiers par une clé commune
join réunit les lignes de deux fichiers lorsque leurs champs de clé ont la même valeur. Par défaut, il utilise le premier champ, exige des entrées triées selon cette clé et affiche seulement les correspondances. Il associe des valeurs de champs, alors que paste assemble les lignes par position.
Préparez donc les deux entrées avec le même séparateur, les mêmes règles de comparaison et la même locale. Une clé absente ou dupliquée change le nombre de résultats : une jointure ne doit pas être supposée automatiquement complète ou strictement un-à-un. Les exemples utilisent GNU join et son option --check-order ; consultez man join pour votre système.
Préparer des données sans modifier les originaux
Exécutez cette préparation dans Bash. Elle crée un répertoire neuf avec des noms et des scores fictifs :
join_lab=$(mktemp -d "$HOME/join-lab.XXXXXX")
cd -- "$join_lab"
printf 'b Bob\na Ana\nc Cat\n' > names.txt
printf 'a 7\nb 12\nd 5\n' > scores.txt
Le premier champ est l'identifiant. Le fichier des noms est volontairement désordonné. Les identifiants a et b sont communs, c ne possède pas de score, et d ne possède pas de nom dans l'autre fichier. Le répertoire de travail ne contient que ces données d'exercice ; vous pourrez en sortir avec cd "$HOME".
Trier la clé puis effectuer la jointure
Créez des copies triées, puis joignez-les :
LC_ALL=C sort -k1b,1 names.txt > names.sorted
LC_ALL=C sort -k1b,1 scores.txt > scores.sorted
LC_ALL=C join --check-order names.sorted scores.sorted
a Ana 7
b Bob 12
Par défaut, les champs d'entrée sont séparés par des suites de blancs et les blancs initiaux sont ignorés. Le tri -k1b,1 délimite le premier champ et ignore ses blancs initiaux conformément à ce comportement. La sortie contient la clé, les autres champs du premier fichier, puis ceux du second.
LC_ALL=C fixe ici une comparaison textuelle reproductible pour les deux tris et la jointure. N'ajoutez pas sort -n simplement parce que les clés ressemblent à des nombres : join doit recevoir l'ordre correspondant à sa propre comparaison des clés. Les réglages de sort et de ses champs de comparaison doivent être cohérents avec ceux de join.
--check-order demande explicitement à GNU join de refuser une entrée désordonnée. Si la commande échoue, ne considérez pas une éventuelle sortie partielle comme un résultat complet. Sans cette vérification explicite, l'absence de diagnostic ne remplace pas le contrôle des conditions de tri.
Conserver ou isoler les clés manquantes
-a 1 ajoute aux correspondances les lignes du premier fichier qui n'ont pas de partenaire :
LC_ALL=C join --check-order -a 1 names.sorted scores.sorted
a Ana 7
b Bob 12
c Cat
Pour afficher seulement les lignes sans correspondance du premier fichier, utilisez -v 1 :
LC_ALL=C join --check-order -v 1 names.sorted scores.sorted
Le résultat est uniquement c Cat. De même, -v 2 sur ces fichiers donne d 5. Les numéros 1 et 2 désignent les fichiers d'entrée, pas le numéro de champ.
Pour conserver aussi les absences des deux côtés dans une sortie de structure fixe, sélectionnez les champs explicitement :
LC_ALL=C join --check-order -a 1 -a 2 -e 'NA' -o '0,1.2,2.2' names.sorted scores.sorted
a Ana 7
b Bob 12
c Cat NA
d NA 5
Dans -o, 0 représente la clé de jointure, 1.2 le deuxième champ du premier fichier et 2.2 celui du second. -e 'NA' donne une valeur de remplacement aux champs manquants sélectionnés. Choisissez un marqueur compatible avec vos données, pour ne pas le confondre avec une vraie valeur.
Changer le séparateur ou le champ de clé
Pour des données séparées par des deux-points, appliquez -t ':' au tri et à la jointure :
printf 'b:Bob\na:Ana\n' > users.txt
printf 'a:reader\nb:writer\n' > roles.txt
LC_ALL=C sort -t ':' -k1,1 users.txt > users.sorted
LC_ALL=C sort -t ':' -k1,1 roles.txt > roles.sorted
LC_ALL=C join --check-order -t ':' users.sorted roles.sorted
a:Ana:reader
b:Bob:writer
Avec un séparateur explicite, chaque occurrence de ce caractère délimite les champs et les blancs sont significatifs. Ne reprenez donc pas sans réflexion l'option -b utilisée dans l'exemple de séparation par blancs.
Si la clé n'occupe pas le même champ dans les deux fichiers, indiquez-la avec -1 et -2. Voici un premier fichier dont la clé est en deuxième position :
printf 'Bob b\nAna a\n' > names-key-second.txt
LC_ALL=C sort -k2b,2 names-key-second.txt > names-key-second.sorted
LC_ALL=C join --check-order -1 2 -2 1 names-key-second.sorted scores.sorted
Vous retrouvez a Ana 7 puis b Bob 12. Le premier fichier est trié sur son deuxième champ, tandis que le second conserve son tri sur le premier. Les numéros de champ commencent à 1.
Prévoir plusieurs résultats pour une clé dupliquée
Une même clé répétée dans les deux fichiers produit chaque combinaison correspondante. Deux lignes d'un côté et deux de l'autre donnent ici quatre résultats :
printf 'a Ana\na Alice\n' > names-duplicate.txt
printf 'a 7\na 8\n' > scores-duplicate.txt
LC_ALL=C join --check-order names-duplicate.txt scores-duplicate.txt
a Ana 7
a Ana 8
a Alice 7
a Alice 8
Les clés sont déjà triées dans cet exemple ; l'ordre des autres champs n'est pas requis pour cette jointure. Vérifiez les doublons en amont si votre application attend une relation un-à-un. Ne retirez pas arbitrairement des lignes pour obtenir le nombre de résultats espéré : cherchez d'abord ce que représentent les enregistrements.
Enregistrer et contrôler le résultat
Choisissez un nouveau fichier de sortie, puis vérifiez le statut de la commande avant d'utiliser ses données :
LC_ALL=C join --check-order names.sorted scores.sorted > joined.txt
printf 'Statut : %s\n' "$?"
cat joined.txt
Avec les données préparées ici, le statut attendu est 0 et le fichier contient les deux lignes a Ana 7 et b Bob 12. Un échec de vérification impose de corriger le tri et de relancer la commande ; une sortie partielle ne doit pas poursuivre un traitement automatisé. Dans un script, testez le statut directement avant de passer à l'étape suivante.
Le nom de sortie doit être distinct des entrées et ne pas écraser de données à conserver. Les fichiers initiaux sont restés intacts : pour reprendre l'exercice, corrigez les paramètres puis recréez seulement leurs copies triées.
| Option | Rôle |
|---|---|
-t caractère |
Définir le séparateur d'entrée et de sortie. |
-1 N, -2 N |
Choisir le champ de clé dans chacun des deux fichiers. |
-a 1, -a 2 |
Ajouter les lignes sans partenaire du fichier indiqué. |
-v 1, -v 2 |
Afficher seulement les lignes sans partenaire. |
-o liste |
Choisir les champs de sortie et leur ordre. |
-e texte |
Remplacer les champs de sortie manquants sélectionnés. |
--check-order |
Avec GNU join, refuser explicitement une entrée désordonnée. |
Les règles complètes figurent dans le manuel officiel de GNU join, notamment ses sections sur le tri préalable des fichiers et les options de jointure et de sortie.




