Linux - Comparer deux versions du même script
Utilisez une astuce simple en ligne de commande Linux avec diff, grep et awk pour comparer deux versions du même script Bash. Identifiez rapidement les fonctions manquantes ou nouvelles entre deux versions d'un fichier ou entre deux dossiers entiers.
Traduction automatique
Cet article a plus d'un an, mais il a été relu le 30 juillet 2026 — son contenu est toujours exact.
Cet article fait partie de la série Écrire de meilleurs scripts Bash :
- Bash - ASCII art
- Bash - Charger des variables d'environnement depuis un fichier
- Bash - Script pour ajouter des fonctionnalités de log à votre script
- Bash - Afficher sur la console et dans un fichier de log en même temps
- Linux - Comparer deux versions du même script
- Linux - Trier les fonctions dans un script Bash
- Linux - Générer de la documentation à partir de scripts Bash
- Linux - Tirez parti du nombre de CPU dont vous disposez ; lancez des jobs concurrents
- Linux - Utiliser une barre de progression dans vos scripts
- Linux - Scripts Bash - Lancer des tests unitaires avec bats/bats

Cet article montre comment comparer deux versions du même script Bash : on extrait les noms de fonctions de chaque fichier avec grep/awk, on les trie, puis on compare les deux listes triées avec diff --side-by-side. On voit ainsi quelles fonctions ont été ajoutées, supprimées ou renommées, quel que soit leur ordre dans le fichier. L'astuce est ensuite étendue en un script compare.sh qui applique la même comparaison à tous les scripts de deux dossiers.
Toujours confronté au problème de devoir comparer deux versions du même script (voir l'article Linux : comparer deux dossiers/fichiers dans la console), cette fois nous allons considérer que le fichier à comparer est un script Bash et que nous en avons deux versions.
Et que nous avons peut-être fait évoluer les deux fichiers différemment, c'est-à-dire que l'un, l'autre, ou même les deux, ont pu être modifiés.
L'objectif est donc de comparer les versions et de mettre en évidence les différences.
Résultat

Deux listes de fonctions triées, côte à côte : tout ce qui n'apparaît que d'un seul côté est une fonction que l'autre version n'a pas — peu importe où elle était déclarée dans le fichier.
Créer quelques fichiers pour cet article
Pour pouvoir reproduire les exemples utilisés dans cet article, si besoin, créez deux fichiers.
Disons /tmp/bash/console.sh pour le premier fichier, avec ce contenu :
#!/usr/bin/env bash
function console::printCyan() {}
function console::askYesNo() {}
function console::printRed() {}
function console::printError() {}
function console::banner() {}Ce fichier définit une bibliothèque de fonctions utilitaires pour l'affichage console avec du formatage coloré et des interactions utilisateur. Les fonctions permettront d'afficher du texte en cyan, rouge, des messages d'erreur, des bannières et de poser des questions oui/non avec des codes couleur pour une meilleure lisibilité.
Et, pour /tmp/bash/console_v2.sh, nous ajoutons deux nouvelles fonctions, printGreen et printBlue, dans cet ordre :
#!/usr/bin/env bash
function console::printCyan() {}
function console::askYesNo() {}
function console::printRed() {}
function console::printError() {}
function console::banner() {}
function console::printGreen() {}
function console::printBlue() {}Ce fichier définit une bibliothèque de fonctions utilitaires pour la console, organisées avec un préfixe de namespace console::. Les fonctions permettent d'afficher du texte coloré (cyan, rouge, vert, bleu), de gérer les erreurs, de poser des questions oui/non à l'utilisateur, et d'afficher des bannières. Pour l'instant, toutes les fonctions sont vides et attendent leur implémentation.
Obtenir la liste des fonctions d'un script Bash
Pour obtenir la liste des fonctions déclarées dans un script (disons /tmp/bash/console.sh), il suffit de lancer la commande ci-dessous :
Cette commande récupère toutes les fonctions du fichier, c'est-à-dire les lignes commençant par le mot function suivi d'un caractère d'espacement, puis du nom de la fonction, puis de parenthèses. Et, pour finir, elle trie la liste :

Comparer les deux versions du même script Bash et voir quelles fonctions sont dans l'un et pas dans l'autre
Peu importe l'ordre dans lequel les fonctions sont déclarées : le script ci-dessous, que vous pouvez copier-coller dans la console, va récupérer la liste des fonctions des deux fichiers, trier la liste et comparer quelles fonctions sont dans une version et absentes de l'autre — c'est la commande et le résultat affichés en haut de cet article, où l'on voit immédiatement que le second fichier compte deux ajouts.
Bien sûr, si nous ajoutons une nouvelle fonction dans console.sh et que nous en supprimons une existante, par exemple, nous le voyons aussi :

Sur l'image ci-dessus, on voit trois indicateurs au milieu de l'écran :
> console::printBlue()
console::printPurple() | console::printGreen()
console::verbose() | console::printRed()
La ligne avec l'indicateur > signifie que console::printBlue() n'a été trouvée que dans le second fichier : notre premier fichier ne déclarait donc pas printBlue.
Et les lignes avec l'indicateur | signalent une divergence. Des deux côtés, nous avions trié notre liste : si la même fonction avait été présente des deux côtés, nous aurions eu une correspondance. Ce n'est pas le cas ici. D'un côté nous avons par exemple printPurple alors que de l'autre nous avons printGreen. Et nous avons verbose et, de l'autre côté, printRed. On peut en conclure que, dans le premier fichier, nous n'avons pas printGreen ni printRed et que nous n'avons pas printPurple ni verbose dans le second.
En ajoutant printBlue, printGreen et printRed dans notre premier fichier, on obtient maintenant :

On voit donc apparaître un nouvel indicateur < : la fonction n'a été trouvée que dans le premier fichier et pas dans le second. Une fois de plus, nous avons la confirmation que nous avons deux nouvelles fonctions (printPurple et verbose) dans notre premier fichier et pas dans le second.
À ce stade, notre /tmp/bash/console.sh contient ceci :
#!/usr/bin/env bash
function console::printCyan() {}
function console::askYesNo() {}
function console::printPurple() {}
function console::verbose() {}
function console::printError() {}
function console::banner() {}
function console::printBlue() {}
function console::printGreen() {}
function console::printRed() {}Ce fichier définit une bibliothèque de fonctions utilitaires pour formater et afficher du texte dans le terminal avec différentes couleurs et styles. Il sert de module réutilisable que d'autres scripts peuvent importer pour obtenir des messages colorés et structurés sans avoir à redéfinir ces fonctions à chaque fois.
et, pour /tmp/bash/console_v2.sh :
#!/usr/bin/env bash
function console::printCyan() {}
function console::askYesNo() {}
function console::printRed() {}
function console::printError() {}
function console::banner() {}
function console::printGreen() {}
function console::printBlue() {}Ce fichier définit une bibliothèque de fonctions utilitaires pour afficher du texte coloré et interagir avec l'utilisateur dans le terminal. Les fonctions permettent d'imprimer des messages en différentes couleurs (cyan, rouge, vert, bleu) et de gérer l'affichage d'erreurs, de bannières et de questions oui/non.
L'ordre n'a pas d'importance
Contrairement à une comparaison avec diff, l'ordre dans lequel les fonctions apparaissent dans les scripts n'a aucune importance, puisque nous les trions. Si vous préférez corriger la cause plutôt que la contourner, Linux - Trier les fonctions dans un script Bash réordonne les fonctions directement dans les fichiers.
Comparer les scripts Bash de deux dossiers
Dans le chapitre précédent, nous avons vu comment comparer deux versions du même script. Allons un cran plus loin et comparons deux dossiers : pour chaque script des deux dossiers, lançons une comparaison.
Pour cela, créez le script compare.sh sur votre disque dur avec ce contenu :
#!/usr/bin/env bash
clear
if [ ! $# -eq 2 ]; then echo "Usage: $0 <folder_1> <folder_2>" exit 1fi
sourceFolder="$1"compareWithFolder="$2"
[[ ! -d "${sourceFolder}" ]] && echo "Error: Source folder ${sourceFolder} not found." && exit 1[[ ! -d "${compareWithFolder}" ]] && echo "Error: CompareWith folder ${compareWithFolder} not found." && exit 1
pushd "${sourceFolder}" >/dev/null || exit 1
printf "\e[37;1m%s\e[0;1m\n\n" "Compare .sh scripts and detects functions that are in one of the files but not in the other between these two folders:"printf "\e[37;1m%s\e[0;1m\n" "LEFT SIDE = ${sourceFolder}"printf "\e[37;1m%s\e[0;1m\n\n" "RIGHT SIDE = ${compareWithFolder}"
printf "\e[37;1m%s\e[0;1m\n\n" "Legend:"printf "\e[37;1m1/ \e[34;1m%s\e[0;1m\n" "name1 <"printf "\e[37;1m\t%s\e[0;1m\n\n" "That function only exist in the first file; not in the second one"
printf "\e[37;1m2/ \e[34;1m%s\e[0;1m\n" "name1 | name2"printf "\e[37;1m\t%s\e[0;1m\n\n" "The function name1 only exists in the first file and name2 only exists in the second file"
printf "\e[37;1m3/ \e[34;1m%s\e[0;1m\n" " > name2"printf "\e[37;1m\t%s\e[0;1m\n\n" "The function name2 only exists in the second file"
printf "\e[41;1m%s\e[0;1m\n" "Warning: this script checks whether a function is present in one of the files and not in the other,"printf "\e[41;1m%s\e[0;1m\n" "but does not check whether the function code is identical. It just checks whether it is present or not."
for bashScript in *.sh; do if [[ -f "${compareWithFolder}/${bashScript}" ]]; then ( FILE1="${sourceFolder}/${bashScript}" FILE2="${compareWithFolder}/${bashScript}" printf "\e[32;1m%s\e[0;1m\n" "File ${bashScript}" diff --suppress-common-lines --side-by-side --width 83 \ <(grep -P "^(function\s+.*)\(\)" "${FILE1}" | awk '{print $2}' | sort) \ <(grep -P "^(function\s+.*)\(\)" "${FILE2}" | awk '{print $2}' | sort) && \ printf "\e[32;1m%s\e[0;1m\n" "The two files are identical" ) fidone
popd >/dev/null || exit 1Ce script compare deux dossiers contenant des fichiers bash et détecte les fonctions présentes dans un fichier mais pas dans l'autre. Il affiche les différences de manière visuelle avec des légendes explicatives, en utilisant diff pour comparer les listes de fonctions extraites de chaque fichier correspondant.
Maintenant, pour l'exécuter, lancez simplement ./compare.sh foldername1 foldername2. Vous obtiendrez quelque chose comme ci-dessous : pour chaque script présent dans les deux dossiers (les scripts présents dans un seul dossier sont ignorés), vous obtenez le nom du script (comme array.sh) suivi du texte The two files are identical si les deux fichiers sont identiques ou, sinon, une liste de noms de fonctions et l'indicateur déjà vu, à savoir <, > ou |.

Avec ce script, il est facile de garder l'un des deux dossiers comme master (le dossier de gauche), c'est-à-dire d'y reproduire toutes les fonctions qui auraient été ajoutées à un script du second dossier (celui qui correspond à la colonne de droite).
Une fois une fonction identifiée, il suffit d'ouvrir le fichier de droite et de copier-coller la fonction dans le fichier correspondant du dossier de gauche.
En ajoutant | grep -E -v "<$" à notre instruction grep, nous pouvons améliorer le script en ignorant les cas où des fonctions ont été ajoutées uniquement dans le dossier de gauche. Imaginez le besoin suivant : Dans le dossier de droite, si j'ai ajouté des fonctions à mes scripts, quelles sont ces fonctions afin que je puisse les copier-coller dans les scripts du dossier de gauche ?
#!/usr/bin/env bash
clear
if [ ! $# -eq 2 ]; then echo "Usage: $0 <folder_1> <folder_2>" exit 1fi
sourceFolder="$1"compareWithFolder="$2"
[[ ! -d "${sourceFolder}" ]] && echo "Error: Source folder ${sourceFolder} not found." && exit 1[[ ! -d "${compareWithFolder}" ]] && echo "Error: CompareWith folder ${compareWithFolder} not found." && exit 1
pushd "${sourceFolder}" >/dev/null || exit 1
printf "\e[37;1m%s\e[0;1m\n\n" "Compare .sh scripts and detects functions that are in one of the files but not in the other between these two folders:"printf "\e[37;1m%s\e[0;1m\n" "LEFT SIDE = ${sourceFolder}"printf "\e[37;1m%s\e[0;1m\n\n" "RIGHT SIDE = ${compareWithFolder}"
printf "\e[37;1m%s\e[0;1m\n\n" "Legend:"printf "\e[37;1m1/ \e[34;1m%s\e[0;1m\n" "name1 <"printf "\e[37;1m\t%s\e[0;1m\n\n" "That function only exist in the first file; not in the second one"
printf "\e[37;1m2/ \e[34;1m%s\e[0;1m\n" "name1 | name2"printf "\e[37;1m\t%s\e[0;1m\n\n" "The function name1 only exists in the first file and name2 only exists in the second file"
printf "\e[37;1m3/ \e[34;1m%s\e[0;1m\n" " > name2"printf "\e[37;1m\t%s\e[0;1m\n\n" "The function name2 only exists in the second file"
printf "\e[41;1m%s\e[0;1m\n" "Warning: this script checks whether a function is present in one of the files and not in the other,"printf "\e[41;1m%s\e[0;1m\n" "but does not check whether the function code is identical. It just checks whether it is present or not."
for bashScript in *.sh; do if [[ -f "${compareWithFolder}/${bashScript}" ]]; then ( FILE1="${sourceFolder}/${bashScript}" FILE2="${compareWithFolder}/${bashScript}" printf "\e[32;1m%s\e[0;1m\n" "File ${bashScript}" diff --suppress-common-lines --side-by-side --width 83 \ <(grep -P "^(function\s+.*)\(\)" "${FILE1}" | awk '{print $2}' | sort) \ <(grep -P "^(function\s+.*)\(\)" "${FILE2}" | awk '{print $2}' | sort) | grep -E -v "<$" ) fidone
popd >/dev/null || exit 1Ce script compare deux dossiers contenant des fichiers bash pour trouver les fonctions qui existent dans un fichier mais pas dans l'autre. Il extrait les noms de fonction de chaque fichier .sh, les trie, puis utilise diff pour afficher les différences de manière lisible avec une légende expliquant le format de sortie.
Si nous lançons cette nouvelle version du script sur exactement les mêmes fichiers, les lignes se terminant par < sont maintenant masquées (présentes uniquement dans le dossier de gauche) et nous n'obtenons que les cas où une fonction est présente dans le dossier de droite :

Il devient encore plus facile d'identifier ces fonctions et de les copier-coller vers la gauche, par exemple.
Cet article fait partie de la série Écrire de meilleurs scripts Bash :
- Bash - ASCII art
- Bash - Charger des variables d'environnement depuis un fichier
- Bash - Script pour ajouter des fonctionnalités de log à votre script
- Bash - Afficher sur la console et dans un fichier de log en même temps
- Linux - Comparer deux versions du même script
- Linux - Trier les fonctions dans un script Bash
- Linux - Générer de la documentation à partir de scripts Bash
- Linux - Tirez parti du nombre de CPU dont vous disposez ; lancez des jobs concurrents
- Linux - Utiliser une barre de progression dans vos scripts
- Linux - Scripts Bash - Lancer des tests unitaires avec bats/bats





