Compare Two Directories in Bash

Written by: Aditya Harsh   |   Last updated: March 14, 2024

Comparing two directories helps identify missing, added, and modified files. This is necessary for synchronization when we want to update one directory to match the contents of another. This acts as the underlying principle of version control tools like git and svn.

Here in this guide, we learn different approaches to compare directories in Linux Bash.

Commands to compare directories

Following commands you can use to compare directories in Linux.

  • diff command: By using -qr option.
  • Dry run rsync: Use -n -rv --delete dir1/ dir2/.
  • meld: Visually compare.
  • tree command: Gets overview, needs to manually check.

Using diff command

The diff command is generally used to compare files but it can compare directories and its contents.

Example:

diff -qr dir1 dir2

If there are no differences between the directories, the above diff command will produce no output. If there are differences, will list them.

Where,

-q: Known as "quiet" mode. When comparing files, it reports only that files differ, not the specific details of the difference.

-r: Stands for "recursive," which tells diff to go into directories recursively.

Output:

$ tree dir1/
dir1/
├── commfile.txt
├── dir11
│   └── file11.txt
├── dirX
└── file1.txt

2 directories, 3 files
$ tree dir2/
dir2/
├── commfile.txt
├── dir22
│   └── file22.txt
├── dirX
└── file2.txt

2 directories, 3 files
$ diff -qr dir1 dir2
Only in dir1: dir11
Only in dir2: dir22
Only in dir1: file1.txt
Only in dir2: file2.txt
$

Let's see how diff compared dir1 and dir2:

  1. "Only in dir1: dir11" - This tells you that dir1 contains a directory named dir11 that dir2 does not have.
  2. "Only in dir2: dir22" - Conversely, this indicates that dir2 has a directory named dir22 not present in dir1.
  3. "Only in dir1: file1.txt" - This means that there's a file named file1.txt in dir1 not present in dir2.
  4. "Only in dir2: file2.txt" - This indicates that dir2 contains a file named file2.txt not present in dir1.

The command does not mention dirX, suggesting that this directory exists in both dir1 and dir2. Since the -q (quiet) option is used, diff does not report any differences within dirX if the files/subdirectories inside it are identical in both locations. If there were any differences in content or any additional/missing files within dirX in either directory, diff would include those in its output.

Similarly, commfile.txt is not mentioned in the differences, implying that this file exists in both dir1 and dir2 and is identical, as the -q option suppresses the detailed output of differences.

The command does not report differences for files file11.txt and file22.txt because diff compares the contents of directories at the same level. Since their parent directories dir11 and dir22 are different (i.e., they only exist in one of the directories being compared), the command doesn't proceed to compare their contents.

Let's use a bash script to verify two directories are identical. We will make use of diff for this.

#!/bin/bash
if diff -rq "$1" "$2" &> /dev/null; then
    echo "The directories are identical."
else
    echo "The directories are different."
fi

Output:

 ./checkdirs.sh dir1 dir2
The directories are different.

Alternative methods

Good to know there are a few other alternative methods to compare directories.

Using rsync command

You can use rsync which is mainly used for transferring and synchronizing files, but here you can do a dry run to get a report showing the differences between the source and destination directories.

Example:

rsync -n -rv --delete dir1/ dir2/

where the options are used for:

  • -n: Simulate the operation but not actually perform any changes. It'll only report what it would do.
  • -r: recursively, which is necessary for directory comparison.
  • -v: Stands for verbose. It makes rsync report in detail about what it would do.
  • --delete: Report files that exist in dir2 but not in dir1, simulating that they would be deleted to make dir2 identical to dir1.

Output:

sending incremental file list
deleting dir22/file22.txt
deleting dir22/
deleting file2.txt
commfile.txt
file1.txt
dir11/
dir11/file11.txt

sent 199 bytes  received 73 bytes  544.00 bytes/sec
total size is 35  speedup is 0.13 (DRY RUN)

Here's what the output is indicating:

  • deleting dir22/file22.txt and deleting dir22/: "dir22" and its file "file22.txt" exist in "dir2" but not in "dir1/". The --delete option indicates these would be deleted from "dir2" to mirror "dir1/".
  • deleting file2.txt: This file is in "dir2" but not in "dir1/". It would be deleted from "dir2" for the two directories to be in sync.
  • commfile.txt: This file exists in both directories. Since there's no indication of deletion or transfer, it's likely identical in both places, so no action is required.
  • file1.txt: This file is present in "dir1/" but not in "dir2". It would be copied to "dir2".
  • dir11/ and dir11/file11.txt: This directory and its file exist in "dir1/" but not in "dir2". They would be copied to "dir2".

The dirX directory is not mentioned in the output, implying that it exists in both "dir1/" and "dir2" and is identical, requiring no changes.

Using tree command

The tree command can give a structured view of files and directories.

Example:

tree dir1 dir2

Output

dir1
├── commfile.txt
├── dir11
│   └── file11.txt
├── dirX
└── file1.txt
dir2
├── commfile.txt
├── dir22
│   └── file22.txt
├── dirX
└── file2.txt

2 directories, 3 files

This will give you a hierarchical view of all the files and directories under "dir1" and "dir2", but you'll have to do the comparison manually by looking at the outputs.

meld command

meld is a visual diff tool that makes it easier to compare changes in files as well as directories.

Example:

meld dir1 dir2
compare two directories using meld

The above command pops up a graphical interface showing a side-by-side comparison of the directories named dir1 and dir2. You can visualize the differences between files or directories. Using colors and linking lines you can easily see where content is added, removed, or modified. You can also compare using the file size and timestamp.

About The Author

Aditya Harsh

Aditya H

Aditya Harsh graduated from BITS Pilani, India with a Bachelor’s in Computer Science in 2015. Since then he has been working as a Software Developer and specializes in automation, especially in Java, and Bash scripting. Over these years, he has worked on a lot of cutting-edge technologies and enjoys using his skills to contribute to technological advances. He believes in the power of knowledge and takes great joy in sharing what he has learned.

SHARE

Comments

Please add comments below to provide the author your ideas, appreciation and feedback.

Leave a Reply

Leave a Comment