Unix : diff

de | 2017-06-09

Introduction

Unix, c’est un peu comme les façades parisiennes : vous pensez avoir tout vu, parcouru mille fois les rues de votre quartier, puis vous vous rendez compte qu’à deux pas se trouve une sculpture monumentale, une fontaine dissimulée ou un tag bariolé.

Aujourd’hui, nous vous proposons de prendre quelques minutes pour détailler une commande dont vous vous servez comme on se sert d’un tire-bouchon. Ça à l’air trivial mais c’est rudement bien pensé, quand même.

Développement

« diff », donc, pour les néophytes , est une commande Unix permettant de comparer ligne à ligne le contenu de deux fichiers entre eux et d’afficher leur différence. Mieux que ça : elle permet de générer un patch pour appliquer ces différences. Une utilisation typique : comparer deux scripts pour tenter de retrouver la ligne où vous avez par mégarde introduit une erreur. Elle existe depuis 1970, donc un peu de respect.

Un exemple ? Volontiers !

Fichier 1 :


$ cat fichier1.txt 
1 I like to move it
2 move it
3 I like to 

 

Fichier 2 :

$ cat fichier2.txt 
1 I like to move it
2 Move it
3 I like to 
4 Move it !
# cette chanson va rester dans la tête

Et la différence des deux :

$ diff fichier1.txt fichier2.txt
2c2
< 2 move it
---
> 2 Move it
3a4,5
< 4 Move it !
> # cette chanson va rester dans la tête

 

Que nous dit cette sortie ? Il y a des différences dans un sens et dans un autre :

« 2c2 » : la ligne numéro 2 est modifiée ( « c » est pour « changed »). Il y a une majuscule dans le second et pas dans le premier.

« 3a4,5 » : à partir de la ligne 3, une ligne 4 et une ligne 5 ont été ajoutées (« a » signifie « append »).

Si nous avions supprimé la deuxième ligne, nous aurions eu ce retour :

2d1
< 2 move it

… signifiant que la deuxième ligne du premier fichier manque après la première ligne du second. « d » est pour « delete ».

« diff » donne des intervalles séparés par des virgules, donc « 1,7c1,4 » se lit comme « Les lignes 1 à 7 du premier fichier remplacent les lignes 1 à 4 du second ». Ce qui signifie aussi que la ligne 8 du premier et la ligne 5 du second sont identiques.

Pour générer le script de patch : « -e » ou « –ed » :


$ diff -e fichier1.txt fichier2.txt | tee change.patch
3a
4 Move it !
# cette chanson va rester dans la tête
.
2d

 

 

Le « tee » est optionnel. C’est juste pour vous montrer directement le résultat. Nous aurons donc 2 lignes ajoutées après la troisième et la seconde sera supprimée.

Et pour l’appliquer :


patch  fichier1.txt < change.patch

 

 

Le fichier1.txt est maintenant strictement identique au fichier2.txt.

Conclusion

Tout ceci est bien beau, d’une simplicité enfantine sur un fichier de 4 lignes.

Cela devient compliqué lorsqu’il y a des milliers de lignes et des centaines de différences. Et, pour « diff » comme pour « patch », il existe une grande quantité d’options permettant d’affiner la sensibilité des comparaisons (sur les espaces, par exemple) et l’effet de la correction (fusion des différences dans un sens ou dans un autre, par exemple).

Comme souvent sous Unix, la simplicité est trompeuse.

En général, on utilise « diff » pour un besoin ponctuel et on peste lorsque que les fichiers à comparer sont trop gros pour que cela reste lisible. Prendre le temps de comprendre la sortie vous facilitera la vie, y compris lorsque vous utiliserez des versions graphiques style Windiff. Croyez-nous : ce sera du temps bien investi.