xxd — Hex dump utility — show bytes plus ASCII, or reverse hex back to binary across all 5 shells
Equivalents in every shell
xxd file.binDefault output: offset (hex) + 16 bytes (hex, grouped in pairs) + ASCII gutter. `-c N` changes the bytes-per-line; `-g N` changes the grouping; `-s OFFSET` starts at a byte offset; `-l LEN` limits length. Ships with vim (`vim-common` on Debian/Ubuntu) — practically always available wherever vim is.
xxd file.binSame external `xxd`. macOS ships xxd as part of Apple's vim distribution since the base OS — `/usr/bin/xxd` is always present. No flag differences from GNU/vim xxd on Linux for everyday use.
xxd file.binSame external. Fish has no special pipe handling for xxd output; it's plain text. Common idiom: `xxd file.bin | string match "*deadbeef*"` to grep hex pairs across lines without juggling line-boundary issues.
Format-Hex file.binpwsh-native hex dump. Output: offset + 16-byte hex group + ASCII gutter. `-Count N` limits bytes; `-Offset N` starts at byte offset. Supports multiple files in one call. Works on Windows / Linux / macOS pwsh. No `-i` (C-array) or `-r` (reverse) modes — for those, use `xxd` directly (install via Git for Windows or WSL).
certutil -dump file.bincmd.exe has no native hex viewer. `certutil -dump` is the legacy Microsoft tool, repurposed — outputs hex but with Microsoft-formatted headers. For real `xxd` on Windows install Git for Windows (bundles xxd in `C:\Program Files\Git\usr\bin\xxd.exe`) or use WSL.
Worked examples
Inspect the first 64 bytes of a binary (file magic)
xxd -l 64 file.binFormat-Hex file.bin -Count 64certutil -dump file.bin | head -n 5Emit a C array `unsigned char` definition for embedding
xxd -i logo.png > logo.h$bytes = [IO.File]::ReadAllBytes('logo.png'); $hex = ($bytes | ForEach-Object { "0x{0:x2}" -f $_ }) -join ', '; "unsigned char logo_png[] = {$hex};" | Out-File logo.hReverse a hex dump back into the original binary
xxd -r dump.hex > recovered.bin[IO.File]::WriteAllBytes('recovered.bin', (Get-Content dump.hex | Select-String -Pattern '^[\da-f]{8}: ([\da-f ]+) ' | ForEach-Object { -split $_.Matches[0].Groups[1].Value -join '' -split '(..)' | Where-Object { $_ } | ForEach-Object { [Convert]::ToByte($_, 16) } }))Gotchas
- Default `xxd` output INCLUDES the offset column and ASCII gutter — when feeding to other tools (e.g. comparing two dumps with `diff`), use `xxd -p` (plain) to get just the hex bytes, no offsets, no gutter. `xxd -p -c 0` puts the whole file on ONE line (useful for round-trip-safe text storage of small binaries).
- The `-i` (include) mode emits BOTH the byte array AND a `<filename>_len` size variable in the C output — but the variable is `int`, not `size_t` or `unsigned`. Newer compilers warn; cast or replace the `int` declaration before including in production C.
- `xxd -r` (reverse) requires the EXACT default format with offset and ASCII gutter — if the dump file lost columns or has BOM/CRLF line endings, the reverse silently produces wrong bytes. Use `dos2unix dump.hex` before `xxd -r` on Windows-edited files. `xxd -r -p` reverses plain hex (no offsets).
- `-c 0` (continuous, no line breaks) is xxd 1.10+ (2022) — older vim distributions don't support it. For older xxd, simulate with `xxd -p file | tr -d "\n"`.
- pwsh `Format-Hex` is NOT a drop-in xxd replacement — output format differs (different column widths, no ASCII gutter alignment for non-printable bytes, no `-i` / `-r` modes). For cross-shell pipelines that must produce byte-identical hex dumps, install xxd everywhere via Git for Windows / WSL / Linux package manager.