diff Command: File Comparison, the diff -u Patch Format, and Options
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/workcat config-old.conf# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warncat config-new.conf# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache onThe two files were compared without options.
diff config-old.conf config-new.conf2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache onecho $?1The 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.
| Output | Meaning |
|---|---|
| 2,3c2,3 | Changes lines 2–3 of the first file into lines 2–3 of the second file (change) |
| 5d4 | Deletes line 5 of the first file (delete). Once deleted, it lines up after line 4 of the second file |
| 6a6 | Adds line 6 of the second file after line 6 of the first file (add) |
| < line | A line in the first file |
| > line | A 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.confecho $?0Giving a file that does not exist prints an error message, and the exit code is 2.
diff config-old.conf nosuch.confdiff: nosuch.conf: No such file or directoryecho $?2A 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 onThe 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 onFor 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.patchecho $?1cat /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 onThe 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.txtListen 80
ServerName example.com
DocumentRoot /var/www/htmlcat case-b.txtlisten 80
ServerName example.com
DocumentRoot /var/www/htmldiff case-a.txt case-b.txt1,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.txt2c2,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.txt2a3
>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.txtecho $?0To 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 onThe 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.conflisten 80 | listen 443
server_name example.com | server_name example.com www.ex
gzip off <
> cache onTo 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.confFiles config-old.conf and config-new.conf differdiff -s config-old.conf config-copy.confFiles config-old.conf and config-copy.conf are identicalThe options are gathered in the two tabs below.
| Option | Copy | Description |
|---|---|---|
| -u, --unified | Prints in the unified format, which bundles up to three lines before and after the changed lines | |
| -c, --context | The context format, which prints the first file's chunk and the second file's chunk separately | |
| -i, --ignore-case | Ignores differences in case | |
| -w, --ignore-all-space | Ignores all whitespace within a line | |
| -b, --ignore-space-change | Ignores only differences in the amount of whitespace | |
| -B, --ignore-blank-lines | Ignores differences in blank lines | |
| -y, --side-by-side | Prints the two files side by side on the left and right | |
| -W, --widthNUM | Sets the width for side-by-side output. The default is 130 columns | |
| --suppress-common-lines | In side-by-side output, leaves out identical lines and prints only differing lines | |
| -q, --brief | Prints only whether the files are the same or different. Prints nothing if they are the same | |
| -s, --report-identical-files | Prints a line saying the files are identical when the two files are the same | |
| -r, --recursive | Compares files inside subfolders as well |
| Option | Copy | Description |
|---|---|---|
| -U, --unifiedNUM | Sets the number of lines before and after to print together in the unified format. The default is 3 | |
| -N, --new-file | Treats a file missing on one side as an empty file | |
| -x, --excludePAT | Excludes files whose names match the pattern from the comparison | |
| -I, --ignore-matching-linesRE | Ignores a difference when all of its changed lines match the regex | |
| -Z, --ignore-trailing-space | Ignores whitespace at the end of a line | |
| -E, --ignore-tab-expansion | Ignores differences caused by converting tabs to spaces | |
| -a, --text | Treats all files as text | |
| --strip-trailing-cr | Strips the carriage return at the end of a line before comparing | |
| --colorWHEN | Colors the output. WHEN is never, always, or auto | |
| -v, --version | Prints 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.
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-v2Only 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-v2Only 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-v2Only 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
Linux · Text
Linux grep command
How to use grep to find and print only the lines containing the string you want in a text file such as a log file.
Linux · Text
Linux sort command: sorting files
sort options and examples for sorting file contents alphabetically or in ascending or descending order.
Linux · Text
Linux uniq command
How to use uniq to keep only one of each duplicate line and count repetitions with -c.
ℹ️ 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.