LearnLinux FoundationsText Processing

diff

diff - a hands-on Linux lab on a real virtual machine.

Compare two files line by line with diff. Read the normal report where < is the first file and is the second, learn the silence of identical files and the exit status scripts read, and meet the brief -q, unified -u, and side-by-side -y forms, all in the practice terminal on a tiny two-file fixture.

Sooner or later you will hold two files that are supposed to be the same. A config you edited and its backup. This week's list and last week's. You need to know exactly what changed. Reading both side by side and squinting is how mistakes slip through. One command does the squinting for you and reports the differences precisely. It is called diff.

diff compares two files line by line and prints only the lines that differ. Lines that match are left out, so what remains is a tight report of the changes and nothing else. That is the whole command, and this lesson is all of it.

The black boxes in this lesson are a practice terminal: a safe sandbox that only checks the one command each step teaches, so you cannot break anything. At the end of the module one real Linux machine boots just for you, and you run the full mission there.

Here is the fixture you will compare all lesson. Two tiny files sit in your home folder. old.txt holds three lines:

line one
line two
line three

And new.txt holds the same three lines with one edit, the middle line changed from line two to line 2:

line one
line 2
line three

Point plain diff at both files, old one first. Type this exact command and press Enter:

diff old.txt new.txt

prompt: student@linuxcamp:~$ answer: diff old.txt new.txt output: 2c2 < line two --- > line 2 hint: Type diff, a space, the old file, a space, the new file: diff old.txt new.txt

Four short lines, and every one of them means something exact. The next step decodes them, because this default shape is the one you will read most and the symbols repay a careful look.

That four-line report is diff's normal format, and it is a set of instructions for turning the first file into the second. Read it piece by piece:

So the whole report says: at line 2, line two became line 2. The lines that matched, line one and line three, are not shown at all, which is exactly what makes the report easy to scan.

The one thing to burn in: < is the first file, > is the second. Get the direction backwards and you will read every diff inside out. First file, less-than, points left and back in time; second file, greater-than, points right and forward.

Here is a habit that trips up nearly everyone the first time. When the two files are exactly the same, diff prints NOTHING at all. No "files are identical" message, no cheerful checkmark, just an empty line and your prompt back.

Compare old.txt against itself to see the silence. Before you press Enter, decide what you expect to appear on screen:

diff old.txt old.txt

prompt: student@linuxcamp:~$ answer: diff old.txt old.txt output: hint: Name the same file twice: diff old.txt old.txt

Empty. That blank result is diff telling you the two files match perfectly. It is not an error and not a hang. In the Unix tradition, no news is good news: a command that has nothing to report says nothing. Remember this so that an empty result reassures you instead of worrying you. If you ever want a command that speaks up either way, that is the -q flag, coming shortly.

diff also answers a yes-or-no question every time it runs, in a channel you do not see on screen: its exit status. Every command leaves behind a number when it finishes. By convention 0 means success. diff uses that number to report its verdict:

You read that hidden number with echo $?, which prints the exit status of the command you just ran. ($? is the shell's memory of the last exit status; it has its own lesson.) Run a diff that you know finds a difference, then ask for the status it left behind:

echo $?

prompt: student@linuxcamp:~$ answer: echo $? output: 1 hint: After the diff that found a change, type echo, a space, then dollar question-mark: echo $?

1, meaning the files differ. That single number is why diff is so useful inside scripts. A script does not read the < and > report; it checks the exit status. 0 means the two files match, so nothing to do. 1 means they differ, so act. 2 means the comparison itself failed, usually a typo in a filename. You will use this the day you write a check that should fire only when a file has changed.

Sometimes you do not care WHAT changed, only WHETHER anything changed. The -q flag, short for quiet or brief, throws away the line-by-line report and prints a single sentence instead: either nothing (files match) or one line saying they differ.

Ask diff the brief question about the two files:

diff -q old.txt new.txt

prompt: student@linuxcamp:~$ answer: diff -q old.txt new.txt output: Files old.txt and new.txt differ hint: Add -q between diff and the filenames: diff -q old.txt new.txt

One plain sentence, Files old.txt and new.txt differ, and no detail. Run the same -q on two files that match and it prints nothing at all, just like plain diff. So -q is the fast triage: it tells you "yes, look closer" or stays silent for "nothing to see," and you drop the flag only when you want the full report.

The normal format is easy for a human to read, but two of the most common tools in Linux, patch and git, speak a different dialect of diff called the unified format. The -u flag prints it. Each of those tools has its own lesson later; for now, just meet the shape, because you will see it constantly.

Ask for the unified view of the same two files:

diff -u old.txt new.txt

A unified diff opens with two header lines naming the files, then a line like @@ -1,3 +1,3 @@ (a hunk header saying which lines this block covers), then the lines themselves. A line marked - is the old side. A line marked + is the new side. Unmarked lines are shared context around the change:

@@ -1,3 +1,3 @@
 line one
-line two
+line 2
 line three

Two honest wrinkles about the real output. First, above the hunk diff -u also prints a --- old.txt and +++ new.txt header, and each carries the file's last-changed TIMESTAMP, which differs on every machine, so it is left out of the display here. Second, notice the swap of symbols: the human format uses < and >, but the unified format uses - and + for the very same old and new sides. Same idea, different marks.

One more view worth knowing. The -y flag prints the two files in two columns next to each other, the first file on the left and the second on the right, so you can see them at a glance. A marker in the middle flags each line that changed: a | means "this line differs between the two files."

diff -y old.txt new.txt

The shared first and last lines line up with a gap between them; only the middle line carries the | change marker:

line one            line one
line two          | line 2
line three          line three

Real diff -y lines up its two columns with tab characters, which are invisible on the page, so the spacing above is stood in with plain spaces to show you the layout. On a live terminal the columns snap to neat tab stops. What is exact and worth carrying away is the | in the middle: it marks the one line, line two versus line 2, that differs, while the matching lines sit quietly on both sides.

Scaffolding off. No command is shown this time. You have every piece you need.

A script you are writing only needs a yes-or-no answer: do old.txt and new.txt differ, or not? You do NOT want the full < and > report, just the single brief line. Pick the flag that makes diff answer briefly, and point it at the two files, old one first.

prompt: student@linuxcamp:~$ answer: diff -q old.txt new.txt output: Files old.txt and new.txt differ hint: Brief means the -q flag. Point diff -q at both files, old first: diff -q old.txt new.txt

One line, from memory. -q collapsed the whole change report down to a single sentence, exactly what a script wants when it only needs to know "did anything change?" You picked the flag and typed the command without a prompt, which is the same recall the real machine will ask of you.

You earned this cheat sheet. Every row is a form of diff you have already run or read:

Two rules carry the whole lesson. In the normal report, < is the FIRST file and > is the SECOND; get that direction right and you can read any diff. And identical files print nothing, leaving exit status 0, while differing files exit 1, which is how scripts tell the two apart without reading a word of the report.

diff shows what changed; its partner patch can APPLY those changes to a file. That is why the unified -u format matters: you save a diff to a file and hand it to patch to replay the edit elsewhere. Two folders full of files? diff -r walks both trees and reports every file that differs. Both patch and -r get their own treatment later; here you built the reading skill they both stand on.

The practice terminal has shown you every everyday form of diff: the normal </> report and how to read it, the silence of identical files, the exit status that scripts read, the brief -q, the unified -u, and the side-by-side -y. Every one of those you typed or traced yourself.

The Text Processing module ends with one real Linux machine, the text-processing capstone mission, and that is where you compare files for real. A VM boots just for you, with its own set of files to line up. Its objectives use exactly what you practiced across this module, diff alongside the other text tools, each of which has its own lesson. One difference from here: the mission shows no commands. You read the objective, recall the flag, and type it. That recall is what makes it stick.

Finish the other Text Processing lessons, then go spot the differences for real.

Practice diff in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.