Viewing files
xxd
Make a hex dump of a file, or turn a hex dump back into binary with -r.
xxd [OPTION...] [INFILE [OUTFILE]]
xxd prints a file as hex with the printable text alongside: an offset, 16 bytes grouped in
pairs, and the same bytes as characters (non-printable ones shown as .). It comes from the
Vim project; on Debian it is its own small xxd package.
Two features set it apart from od and hexdump. It works in reverse: xxd -r turns a
dump (possibly edited) back into bytes, and xxd -r -p turns a plain hex string into binary.
And xxd -i writes a C array of a file, a quick way to embed small assets in a program.
Examples
Hex dump of the start of a file
xxd -l 32 photos/beach.png
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 00000010: 0000 0280 0000 01e0 0802 0000 00ba b34b ...............K
-l 32 limits the dump to 32 bytes. The right column shows the .PNG signature and the
IHDR chunk; in hex, 0280 and 01e0 on the second line are the width and height, 640 and 480.
Spot hidden characters
xxd data/windows.txt
00000000: 6c69 6e65 206f 6e65 0d0a 6c69 6e65 2074 line one..line t 00000010: 776f 0d0a wo..
Each line ends in 0d0a, a carriage return plus newline, which marks a file with Windows line endings.
Plain hex string
xxd -p -l 16 README.md
232064656d6f0a0a4120736d616c6c20
-p (plain) prints the hex digits only, without offsets or text: handy for copying bytes into another tool.
Turn a hex string back into bytes
echo 48656c6c6f2c20776f726c640a | xxd -r -p
Hello, world
-r -p reads plain hex and writes the bytes it describes, here Hello, world and a newline.
Patch a byte by editing the dump
xxd todo.txt > todo.hex
sed -i '1s/6275 7920/4255 5920/' todo.hex
xxd -r todo.hex > todo.new
head -n 1 todo.new
BUY milk
xxd -r reverses a normal dump too. Changing the hex for buy to BUY and converting back
produces a file whose first line is BUY milk. Only the hex columns are read back; the
text column is ignored.
Dump from an offset, or from the end
xxd -s -16 notes.txt
000000ae: 2072 6174 6520 6f6e 2077 6562 3032 2e0a rate on web02..
-s -16 starts 16 bytes before the end of the file. The offset column shows where that is
(0xae, byte 174); -s 100 would start at byte 100 from the beginning.
Change bytes per line and grouping
xxd -c 8 -g 1 -l 16 README.md
00000000: 23 20 64 65 6d 6f 0a 0a # demo.. 00000008: 41 20 73 6d 61 6c 6c 20 A small
-c 8 prints 8 bytes per line and -g 1 puts a space between single bytes instead of pairs.
Show bits instead of hex
xxd -b -l 4 README.md
00000000: 00100011 00100000 01100100 01100101 # de
-b prints each byte as 8 binary digits: 00100011 is # and 00100000 the space.
Generate a C array from a file
xxd -i -l 8 photos/beach.png
unsigned char photos_beach_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a
};
unsigned int photos_beach_png_len = 8; -i writes C source: an array named after the file (with / and . replaced by _) and a
length variable. Here -l 8 keeps it to the 8-byte PNG signature.
Common pitfalls
xxd -rwithout-pexpects the normal dump layout with offsets. Feeding it a bare hex string produces nothing useful; usexxd -r -pfor that.When editing a dump to patch a file, the text column on the right is ignored by
xxd -r. Change the hex digits, not the characters.xxdis not part of POSIX or coreutils. Minimal systems may lack it (on Debian it is the separatexxdpackage);od -t x1is always there.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
xxdis the same program on Linux and macOS (it ships with Vim), so options are identical apart from version differences.
Options worth knowing
A selection, described in our own words. For the full list, see xxd(1) or xxd --help.
| Option | What it does |
|---|---|
-l LEN | Stop after LEN bytes. |
-s [+-]SEEK | Start at byte offset SEEK; a negative value counts from the end. |
-c COLS | Number of bytes per output line (16 by default). |
-g BYTES | Group this many bytes together, separated by spaces (2 by default). |
-p | Plain hex output: no offsets, no text column. |
-r | Reverse: convert a hex dump back into binary. |
-i | Output a C include file: an array with the file's bytes. |
-b | Binary digits instead of hex. |
-u | Use upper-case hex letters. |
-e | Little-endian dump: show groups in reversed byte order. |
-o OFFSET | Add OFFSET to the displayed file positions. |