diff Command: File Comparison, the diff -u Patch Format, and Options

Test environmentRHEL familyAlmaLinux 9.8root account
Text viewing · editing commandsdiffLocation/usr/bin/diff

The diff command is a Linux command that compares two files line by line and prints only the lines that differ. Comparing an old file and a new file that imitate a web server configuration with diff showed the three changed places as the three lines 2,3c2,3, 5d4, and 6a6, and the patch file saved with the -u option listed the same changes with minus and plus signs.

The file names and contents in the output below and the working folder /root/work are example values. All the compared files are small files made for testing.

1️⃣ Basic Usage of the diff Command and Reading Its Output

The basic form of the command is diff, options, the first file, and the second file, in that order. It prints, with line numbers, which lines have to be changed, deleted, or added to make the first file the same as the second file.

The two files used for the comparison are six-line files that imitate a web server configuration.

cd /root/work
cat config-old.conf
# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warn
cat config-new.conf
# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache on

The two files were compared without options.

diff config-old.conf config-new.conf
2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache on
echo $?
1

The output alternates between position lines and content lines. The middle letter of a position line is c for change, d for delete, and a for add, and the numbers to the left of the letter are line numbers in the first file while those to the right are line numbers in the second file. When there is a difference, the exit code is 1.

OutputMeaning
2,3c2,3Changes lines 2–3 of the first file into lines 2–3 of the second file (change)
5d4Deletes line 5 of the first file (delete). Once deleted, it lines up after line 4 of the second file
6a6Adds line 6 of the second file after line 6 of the first file (add)
< lineA line in the first file
> lineA line in the second file
---The boundary between the first file's side and the second file's side in changed lines (c)

Comparing files with the same contents prints nothing and ends with exit code 0.

diff config-old.conf config-copy.conf
echo $?
0

Giving a file that does not exist prints an error message, and the exit code is 2.

diff config-old.conf nosuch.conf
diff: nosuch.conf: No such file or directory
echo $?
2

A script uses these three values to tell same, different, and error apart.

2️⃣ The diff -u Unified Format and Patch Files

The default output shows only the changed lines, so in a configuration file with hundreds of lines it is hard to find which setting those lines are near. Adding -u prints in the unified format (unified), which bundles up to three lines before and after the changed lines with them.

diff -u config-old.conf config-new.conf
--- config-old.conf     2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf     2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
 # app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
 root /var/www/html
-gzip off
 log_level warn
+cache on

The two header lines (---, +++) show the names and modification times of the two files, and the @@ -1,6 +1,6 @@ line marks a chunk (hunk) that bundles 6 lines from line 1 of the first file with 6 lines from line 1 of the second file. In the lines below it, a leading - means a line deleted from the first file, a leading + means a line added to the second file, and a leading space means a line that is identical in both files.

-c is the context format (context). It prints the first file's chunk and the second file's chunk separately, with an exclamation mark in front of changed lines, a minus sign on deleted lines, and a plus sign on added lines.

diff -c config-old.conf config-new.conf
*** config-old.conf     Thu Oct 29 02:24:50 2026
--- config-new.conf     Thu Oct 29 02:24:50 2026
***************
*** 1,6 ****
  # app config
! listen 80
! server_name example.com
  root /var/www/html
- gzip off
  log_level warn
--- 1,6 ----
  # app config
! listen 443
! server_name example.com www.example.com
  root /var/www/html
  log_level warn
+ cache on

For the same changes, -c came out longer than -u because the unchanged lines appear once in each of the two chunks.

Saving the -u output to a file makes that file a patch file. Sending the output to a file still leaves the diff exit code at 1.

diff -u config-old.conf config-new.conf > /root/work/config.patch
echo $?
1
cat /root/work/config.patch
--- config-old.conf     2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf     2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
 # app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
 root /var/www/html
-gzip off
 log_level warn
+cache on

The contents of the saved file are the same as the -u result printed on the screen. Passing this file to the patch command can turn the first file into the same contents as the second file.

3️⃣ diff Options and Ignoring Whitespace and Case

Copying settings by hand produces lines whose contents are the same but differ only in case or whitespace. The second set of example files changes the uppercase L on the first line to lowercase, changes one space on the second line to two, and adds one blank line.

cat case-a.txt
Listen 80
ServerName example.com
DocumentRoot /var/www/html
cat case-b.txt
listen 80
ServerName  example.com

DocumentRoot /var/www/html
diff case-a.txt case-b.txt
1,2c1,3
< Listen 80
< ServerName example.com
---
> listen 80
> ServerName  example.com
>

Compared without options, lines 1–2, which mean the same thing, also come out as changed lines. Ignoring case with -i drops the Listen line and leaves only line 2 of the first file.

diff -i case-a.txt case-b.txt
2c2,3
< ServerName example.com
---
> ServerName  example.com
>

Adding -w ignores all whitespace within a line, so the ServerName line also becomes an identical line, and only the one blank line added at line 3 remains. Using -b, which ignores only the amount of whitespace, instead of -w gave the same result for these files.

diff -i -w case-a.txt case-b.txt
2a3
>

With -B added as well, differences in blank lines are also ignored, so it ended with exit code 0 and no output.

diff -i -w -B case-a.txt case-b.txt
echo $?
0

To view the two files side by side on the left and right, use -y. The default width is 130 columns, so it was reduced with -W 70.

diff -y -W 70 config-old.conf config-new.conf
# app config                            # app config
listen 80                         |     listen 443
server_name example.com           |     server_name example.com www.ex
root /var/www/html                      root /var/www/html
gzip off                          <
log_level warn                          log_level warn
                                  >     cache on

The vertical bar (|) in the middle marks a changed line, < a line only in the first file, and > a line only in the second file. Narrowing the width cuts off long lines. The server_name line showed only up to www.ex on the right.

Adding --suppress-common-lines leaves out the identical lines and keeps only the differing ones.

diff -y --suppress-common-lines -W 70 config-old.conf config-new.conf
listen 80                         |     listen 443
server_name example.com           |     server_name example.com www.ex
gzip off                          <
                                  >     cache on

To check only whether the files are the same or different rather than what the differences are, use -q. When the files are the same, -q prints nothing, so use -s to get a line saying they are identical.

diff -q config-old.conf config-new.conf
Files config-old.conf and config-new.conf differ
diff -s config-old.conf config-copy.conf
Files config-old.conf and config-copy.conf are identical

The options are gathered in the two tabs below.

OptionCopyDescription
-u, --unifiedPrints in the unified format, which bundles up to three lines before and after the changed lines
-c, --contextThe context format, which prints the first file's chunk and the second file's chunk separately
-i, --ignore-caseIgnores differences in case
-w, --ignore-all-spaceIgnores all whitespace within a line
-b, --ignore-space-changeIgnores only differences in the amount of whitespace
-B, --ignore-blank-linesIgnores differences in blank lines
-y, --side-by-sidePrints the two files side by side on the left and right
-W, --widthNUMSets the width for side-by-side output. The default is 130 columns
--suppress-common-linesIn side-by-side output, leaves out identical lines and prints only differing lines
-q, --briefPrints only whether the files are the same or different. Prints nothing if they are the same
-s, --report-identical-filesPrints a line saying the files are identical when the two files are the same
-r, --recursiveCompares files inside subfolders as well
OptionCopyDescription
-U, --unifiedNUMSets the number of lines before and after to print together in the unified format. The default is 3
-N, --new-fileTreats a file missing on one side as an empty file
-x, --excludePATExcludes files whose names match the pattern from the comparison
-I, --ignore-matching-linesREIgnores a difference when all of its changed lines match the regex
-Z, --ignore-trailing-spaceIgnores whitespace at the end of a line
-E, --ignore-tab-expansionIgnores differences caused by converting tabs to spaces
-a, --textTreats all files as text
--strip-trailing-crStrips the carriage return at the end of a line before comparing
--colorWHENColors the output. WHEN is never, always, or auto
-v, --versionPrints version information

🔲 diff Command Simulator

In the simulator below, you can type diff yourself with the example files from the article. You can save a patch file with -u or compare with -i -w -B and -rq, and if you add a line to config-new.conf and compare again, the changed result appears.

diff Command Simulatordiff · root account
[root@server work]#
Use the ↑↓ keys to recall commands you typed earlier.

4️⃣ Comparing Folders with diff -r

When comparing several files at once, such as before and after deploying site files, write folder names instead of file names. The example folders site-v1 and site-v2 both contain index.html and a css folder, while about.html and contact.html exist on only one side.

diff site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
Common subdirectories: site-v1/css and site-v2/css
diff site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>

Comparing folders without options shows files that exist on only one side as [Only in] lines and subfolders only as [Common subdirectories] lines, and does not compare the files inside the subfolders. For index.html, which exists under the same name in both folders, the differences are printed below the [diff site-v1/index.html site-v2/index.html] line. Adding -r also prints the color value changed in style.css inside the css folder.

diff -r site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
diff -r site-v1/css/style.css site-v2/css/style.css
2c2
< h1 { color: #222; }
---
> h1 { color: #0a58ca; }
diff -r site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>

For a folder with many files, first check the list of changed files with -rq, then compare only the files you need again with diff.

diff -rq site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
Files site-v1/css/style.css and site-v2/css/style.css differ
Files site-v1/index.html and site-v2/index.html differ

🔢 FAQ & Recommended Content

cmp compares two files byte by byte and prints only the first position where they differ. Comparing the two configuration files from the article with cmp gave the single line [config-old.conf config-new.conf differ: char 21, line 2]. It is used to check whether compressed files or images, for which a line-by-line comparison is meaningless, are the same.

Pass the original file and the patch file to the patch command in that order ([patch config-old.conf config.patch]). patch changes the original file in place, so write the result to another file with -o or apply it to a copy first.

The --color[=WHEN] option adds color, and WHEN takes never, always, or auto. --color with the value omitted is the same as auto and adds color only when printing to a terminal, so to keep the color when passing the output to another command such as less, use --color=always.

ℹ️ Affiliate Disclosure
This site's content contains affiliate links. When a visitor buys a product or service through one of them, the site receives a commission from the seller. The amount the buyer pays(it goes down during event discounts ↓)does not go up. Posted prices, discounts, and stock reflect the time of writing and may differ, so confirm with the seller before buying. Products are chosen and reviewed by our own standards, and commissions do not affect the order or content of reviews.

Leave a Reply

Your email address will not be published. Required fields are marked *

Prove your humanity: 5   +   8   =