Skip to content
shellmap

compare-objectCompare two collections by element — diff equivalent across all 5 shells

Equivalents in every shell

Bashunix
diff file1 file2

GNU diff. Line-oriented; output uses `<` and `>` to indicate which file each differing line belongs to. `-u` for unified format (the standard for patches), `-r` to recurse directories, `-q` for "files differ" exit-only. For semantically-aware diffs (JSON, XML), reach for specialised tools (`jq`, `diff-so-fancy`).

Zshunix
diff file1 file2

Same external `diff`. Zsh has the `(=)` glob qualifier to compare against a baseline pattern but it does not replace diff. For interactive review, zsh users often pair with `delta` (`brew install git-delta`, point `git diff` at it).

Fishunix
diff file1 file2

Same `diff`. Fish has no native diff equivalent; the `string` builtin does line-set differences via `comm` + sort idioms but is awkward for general use. Reach for `diff` (POSIX) or `delta` (fancy display).

PowerShellwindows
Compare-Object (Get-Content file1) (Get-Content file2)

Aliased as `diff`, `compare`. Returns `[PSCustomObject]` with `.InputObject` and `.SideIndicator` (`<=` = only in reference, `=>` = only in difference, `==` = in both with `-IncludeEqual`). Compares by `[object].Equals()` by default — pass `-Property Name,Size` to compare structured records by named fields.

cmd.exewindows
fc file1 file2

Built-in `fc` (File Compare). `/N` line numbers, `/B` binary mode (byte-by-byte). Output format is verbose and not script-friendly. For automation prefer `comp` (returns errorlevel 1 on diff, 0 on match) or shell out to PowerShell.

Worked examples

Compare two text files line-by-line

Bash
diff file1.txt file2.txt
PowerShell
Compare-Object (Get-Content file1.txt) (Get-Content file2.txt)
cmd.exe
fc file1.txt file2.txt

Show only lines unique to file1

Bash
comm -23 <(sort file1) <(sort file2)
PowerShell
Compare-Object (Get-Content file1) (Get-Content file2) | Where-Object SideIndicator -eq "<="

Compare two objects by a specific property

PowerShell
Compare-Object $old $new -Property Name, Status

Gotchas

  • `Compare-Object` ignores ORDER by default — `Compare-Object @(1,2,3) @(3,2,1)` returns NO differences because both sets contain the same elements. For ordered comparison (diff-style), pass `-SyncWindow 0` or compare via index: `0..($a.Count-1) | ForEach-Object { if ($a[$_] -ne $b[$_]) { $_ } }`.
  • `-IncludeEqual` adds rows for matched items (with `SideIndicator = '=='`) — useful for confirming overlap, otherwise omitted entirely. Without it, you cannot tell apart 'no matches' from 'perfect match' by row count alone (both yield zero output rows).
  • When comparing complex objects without `-Property`, `Compare-Object` uses `.Equals()` — which on `[PSCustomObject]` is reference equality. Two structurally-identical custom objects will appear as different. Always pass `-Property` (or pre-project with `Select-Object`) for record comparison.
  • `-CaseSensitive` flips the underlying comparator for strings — without it, `'Foo'` and `'foo'` are equal. Bash `diff` is case-sensitive by default; scripts porting bash workflows often need to add `-CaseSensitive` to match.
  • `-PassThru` returns the original objects (annotated with a `SideIndicator` NoteProperty) instead of the wrapper `[PSCustomObject]`. Useful when you want to pipe the diffs straight to another cmdlet that expects the original type — e.g. `Compare-Object $oldServices $newServices -PassThru | Where-Object SideIndicator -eq '=>' | Start-Service`.

WSL & PowerShell Core notes

pwsh`Compare-Object` is identical on every pwsh platform — pure object math, no OS-specific code paths. The `diff` alias works everywhere but shadows the system `/usr/bin/diff` on Linux/macOS pwsh hosts; explicit `& /usr/bin/diff` reaches the GNU/BSD tool for text-file work where the unified-diff output is required (e.g. generating patches with `diff -u`). For cross-platform scripts, spell `Compare-Object` to avoid ambiguity.
WSLInside WSL bash, `diff` is the standard tool. To call pwsh `Compare-Object` from WSL: `pwsh.exe -c "Compare-Object (Get-Content a) (Get-Content b)"` via interop, or install pwsh inside the distro. For comparing files that live on different sides of the WSL boundary (one in `~/`, one in `/mnt/c/`), GNU `diff` works transparently because DrvFs presents Windows files as regular paths to the Linux side.

Common tasks using compare-object

Related commands