Compare two files line by line
Show the differences between two text files, line by line.
How to compare two files line by line in each shell
diff -u a.txt b.txt`-u` (unified) is the canonical patch-friendly format (3 lines of context, `+` / `-` / ` ` prefix). `-y` (side-by-side) for human reading. `-r` recursive (diff two DIRECTORIES). `-q` brief (just "differ" / silent). `-w` ignore whitespace; `-i` ignore case; `-B` ignore blank-line changes. Exit code: 0 = identical, 1 = different, 2 = trouble — scripts often check `if ! diff -q a b; then ...`.
diff -u a.txt b.txtSame external `diff`. macOS BSD `diff` lacks `--color=auto` (GNU only) — install via `brew install diffutils` → `gdiff --color=auto`. Or use `colordiff` (`brew install colordiff`, pipe `diff | colordiff`). For interactive merge: `vimdiff a.txt b.txt` opens the diff in vim with `]c` / `[c` jump-to-next-conflict and `do` / `dp` get/put hunks.
diff -u a.txt b.txtSame external. Fish status check: `if diff -q a.txt b.txt >/dev/null; echo same; else; echo different; end`.
Compare-Object (Get-Content a.txt) (Get-Content b.txt)Returns an array of `[PSCustomObject]` with `InputObject` (the differing line) + `SideIndicator` (`<=` = only-in-A, `=>` = only-in-B). NOT a unified diff — order-INSENSITIVE by default (lines appearing in both files in different positions count as MATCHED). For ordered line-by-line: `Compare-Object -SyncWindow 0` makes it position-sensitive. For a real unified diff on pwsh, install `diff` via WSL/Git Bash or use `git diff --no-index a.txt b.txt`.
fc a.txt b.txt`fc` (file compare, NT+) prints differing blocks with `***` separators. `/L` line-mode (default for text), `/B` binary-mode, `/N` show line numbers, `/W` ignore whitespace, `/C` ignore case. Exit 0 = identical, 1 = different, 2 = error. `comp` (cmd) also exists but is BYTE-by-byte — useless for text. For unified diff on cmd: install Git for Windows then use `git diff --no-index`.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **Line-ending mismatches — CRLF vs LF — are the #1 false-positive source**: a file edited on Windows (CRLF `\r\n`) and a "same" file edited on Linux (LF `\n`) show every line as different in `diff` because `\r\n != \n`. Strip CRLFs first: `dos2unix a.txt b.txt` (or `tr -d '\r' < a.txt > a.lf.txt`). pwsh `Compare-Object (Get-Content a.txt) (Get-Content b.txt)` does NOT see this — `Get-Content` splits on either CRLF or LF — but `Compare-Object` on RAW content (`-Raw`) does. Always normalize line endings before diffing files of mixed origin.
- **`diff` vs `git diff --no-index` vs `delta`**: for ad-hoc file comparison, `git diff --no-index a.txt b.txt` works even outside a git repo — and benefits from `git config diff.tool` integrations (delta, difftastic, vimdiff). Plain `diff -u` is more portable for shell scripts (no git dep). For visual review: `delta` (Rust, `cargo install git-delta`) renders syntax-highlighted side-by-side diffs.
- **`Compare-Object` is set-based by default — not order-aware**: `Compare-Object (1,2,3) (3,2,1)` reports NO differences (same SET). For order-sensitive comparison, use `-SyncWindow 0` (forces position-by-position). The default `-SyncWindow 5` allows up to 5 lines of reordering before treating lines as different. This is the wrong default for "are these two text files identical line-for-line" — always pair `Compare-Object` with `-SyncWindow 0` for line-by-line semantics.
- **Directory diff**: `diff -rq dir1 dir2` shows which files differ between two trees (`-q` brief, no content). `diff -rN dir1 dir2 | head` includes new files. For a one-liner sync-status report: `rsync -nrc --delete dir1/ dir2/ | grep -v "^$"` (n = dry-run, c = checksum compare). `Compare-Object (Get-ChildItem -Recurse dir1) (Get-ChildItem -Recurse dir2) -Property Name,Length,LastWriteTime` does the same on pwsh.
Related commands
Related tasks
- Diff two directories recursively— See which files exist only in one directory tree, which differ, and which are identical — for verifying a backup, comparing two checkouts, or spotting accidental changes.
- Find duplicate files by content— Identify files with identical contents across a directory tree (regardless of name) — for cleanup, deduplication, or media library audits.