<!--
  canonical-url: https://www.avonture.be/fr/blog/linux-diff-file-folder
  published:     2024-07-19
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Linux : comparer deux dossiers/fichiers dans la console

> Comparez efficacement deux fichiers ou des dossiers entiers sous Linux avec la commande diff. Des scripts bash avancés pour une comparaison à l'échelle industrielle.

---
![Linux : comparer deux dossiers/fichiers dans la console](/img/v2/bash.webp)

**TL;DR**

Cet article partage des snippets réutilisables basés sur `diff` pour comparer deux fichiers ou deux dossiers entiers depuis la console. On va plus loin que le simple `diff file1 file2` / `diff folder1 folder2` pour permettre des comparaisons répétées et scriptées — avec une variante qui masque le bruit du « only in source » lors de la comparaison d'arborescences.

Nativement, Linux dispose d'un outil en ligne de commande appelé `diff` pour comparer deux dossiers ou fichiers. Comparer deux dossiers est plutôt simple : `diff folder_1 folder2`. Et ce n'est pas plus compliqué pour deux fichiers : `diff file_1 file2`.

Par contre, dès que vous voulez faire ça de façon un peu plus industrialisée (lancer un très grand nombre de comparaisons pour confronter deux versions d'un même projet, par exemple), quelques flags et snippets deviennent bien pratiques.

*Deux cas particuliers sont traités ailleurs sur ce blog : [Compare environment files in the Linux console](/blog/compare-env-files-cli), où l'ordre et les commentaires doivent être ignorés, et [Linux - Compare two versions of the same script](/blog/linux-compare-two-versions-of-the-same-script).*

## Comparer deux fichiers {#compare-two-files}

Compare deux fichiers et n'affiche que les différences. Copiez/collez simplement le code ci-dessous dans votre console et adaptez les trois variables des trois premières lignes.

L'exemple ci-dessous va vérifier un fichier donné (`string.sh`) présent à la fois dans le dossier `src` et dans `./../another_project/src`.

> **Information:**
>
> Vous pouvez réutiliser ce snippet pour n'importe quel fichier (le langage n'a pas d'importance).

**script.sh**

```bash
FILE="string.sh"
FOLDER_SOURCE="src"
FOLDER_COMPARE_WITH="./../another_project/src"

clear

[[ ! -d "${FOLDER_SOURCE}" ]] && printf "\033[1;31mThe folder %s didn't exists\033[0m\n" "${FOLDER_SOURCE}" && return 0
[[ ! -f "${FOLDER_SOURCE}/${FILE}" ]] && printf "\033[1;31mThe file %s didn't exists\033[0m\n" "${FOLDER_SOURCE}/${FILE}" && return 0
[[ ! -d "${FOLDER_COMPARE_WITH}" ]] && printf "\033[1;31mThe folder %s didn't exists\033[0m\n" "${FOLDER_COMPARE_WITH}" && return 0
[[ ! -f "${FOLDER_COMPARE_WITH}/${FILE}" ]] && printf "\033[1;31mThe file %s didn't exists\033[0m\n" "${FOLDER_COMPARE_WITH}/${FILE}" && return 0

printf "\033[1;34m%s %s %s %s\033[0m\n" "Compare" "${FOLDER_SOURCE}/${FILE}" "against" "${FOLDER_COMPARE_WITH}/${FILE}"
printf "\033[1;34m%s \033[1;31m%s \033[1;34m%s \033[1;32m%s\033[0m\n\n" "Below in red sentences from" "${FOLDER_SOURCE}/${FILE}" "and, in green, sentences from"  "${FOLDER_COMPARE_WITH}/${FILE}"

pushd "${FOLDER_SOURCE}" > /dev/null && diff --suppress-common-lines "${FILE}" "${FOLDER_COMPARE_WITH}"/"${FILE}" && echo "Congratulations, the two files are exactly the same" ; popd > /dev/null
```

## Comparer deux dossiers {#compare-two-folders}

Compare deux dossiers et affiche la liste des fichiers présents dans un seul des deux dossiers ou pour lesquels il y a une différence.

**script.sh**

```bash
FOLDER_SOURCE="src"
FOLDER_COMPARE_WITH="./../another_project/src"

clear

[[ ! -d "${FOLDER_SOURCE}" ]] && printf "\033[1;31mThe folder %s didn't exists\033[0m\n" "${FOLDER_SOURCE}" && return 0
[[ ! -d "${FOLDER_COMPARE_WITH}" ]] && printf "\033[1;31mThe folder %s didn't exists\033[0m\n" "${FOLDER_COMPARE_WITH}" && return 0

printf "\033[1;34m%s %s %s %s\033[0m\n" "Compare folder" "${FOLDER_SOURCE}" "against" "${FOLDER_COMPARE_WITH}"

pushd "${FOLDER_SOURCE}" > /dev/null && LC_ALL=C diff --brief --ignore-blank-line . "${FOLDER_COMPARE_WITH}" ; popd > /dev/null
```

Cette variante permet de masquer le message `Only in .`, c'est-à-dire quand un fichier est présent dans le premier dossier (celui de `SOURCE`) et pas dans le second (celui de `COMPARE_WITH`).

*La sortie brute de `diff` n'est pas ce qu'il y a de plus lisible sur terre. Si les fichiers que vous comparez se trouvent dans un repository git, [delta: a Syntax-Highlighted Pager for git diff](/blog/git-delta) rend la même information bien plus agréable à lire.*

**script.sh**

```bash
FOLDER_SOURCE="src"
FOLDER_COMPARE_WITH="./../another_project/src"

clear

[[ ! -d "${FOLDER_SOURCE}" ]] && printf "\033[1;31mThe folder %s didn't exists\033[0m\n" "${FOLDER_SOURCE}" && return 0
[[ ! -d "${FOLDER_COMPARE_WITH}" ]] && printf "\033[1;31mThe folder %s didn't exists\033[0m\n" "${FOLDER_COMPARE_WITH}" && return 0

printf "\033[1;34m%s %s %s %s\033[0m\n" "Compare folder" "${FOLDER_SOURCE}" "against" "${FOLDER_COMPARE_WITH}"

pushd "${FOLDER_SOURCE}" > /dev/null && LC_ALL=C diff --brief --ignore-blank-line . "${FOLDER_COMPARE_WITH}" | grep -v '^Only in \.' ; popd > /dev/null
```
