Skip to content
shellmap

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

Bashunix
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 ...`.

Zshunix
diff -u a.txt b.txt

Same 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.

Fishunix
diff -u a.txt b.txt

Same external. Fish status check: `if diff -q a.txt b.txt >/dev/null; echo same; else; echo different; end`.

PowerShellwindows
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`.

cmd.exewindows
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