.TH XXD 1 "Mar 2026" "Manual page for xxd"
.\"
.\" 21st May 1996
.\" 手册页作者：
.\"    Tony Nugent <tony@sctnugen.ppp.gu.edu.au> <T.Nugent@sct.gu.edu.au>
.\"    由 Bram Moolenaar <Bram@vim.org> 修改
.SH 名称
.I xxd
\- 生成十六进制转储或执行反向操作
.SH 概述
.B xxd
\-h[elp]
.br
.B xxd
[options] [infile [outfile]]
.br
.B xxd
\-r[evert] [options] [infile [outfile]]
.SH 描述
.I xxd
可以生成给定文件或标准输入的十六进制转储。
它也可以将十六进制转储还原回原始的二进制形式。
与
.BR uuencode (1)
和
.BR uudecode (1)
类似，它允许以"邮件安全"的 ASCII 表示形式传输二进制数据，
但其优点是可以解码到标准输出。
此外，它还可用于执行二进制文件修补。
.SH 选项
如果未指定
.I infile
，则读取标准输入。
如果
.I infile
指定为
.RB \` \- '
字符，则从标准输入读取输入。
如果未指定
.I outfile
（或其位置是
.RB \` \- '
字符），则结果发送到标准输出。
.PP
注意：程序使用"懒惰"解析器，除非选项后跟有参数，否则不会检查超过第一个选项字母。
单个选项字母与其参数之间的空格是可选的。
选项参数可以用十进制、十六进制或八进制表示法指定。
因此
.BR \-c8 、
.BR "\-c 8" 、
.B \-c 010
和
.B \-cols 8
都是等效的。
.PP
.TP
.IR \-a " | " \-autoskip
切换自动跳过：单个 '*' 替换全零行。默认关闭。
.TP
.IR \-b " | " \-bits
切换到比特（二进制数字）转储，而非十六进制转储。
此选项将每个字节写为八个"1"和"0"数字，而不是普通的十六进制转储。
每行前面有十六进制的行号，后面跟着 ASCII（或 EBCDIC）表示形式。
命令行开关 \-p 在此模式下无效。可与 \-i 结合使用。
.TP
.IR "\-c cols " | " \-cols cols"
每行格式化
.RI < cols >
个字节。默认 16（\-i 模式: 12，\-ps 模式: 30，\-b 模式: 6）。最大 256。
\-ps 模式无最大值。在 \-ps 模式下，值为 0 时输出为单行。
.TP
.IR \-C " | " \-capitalize
使用 \-i 选项时，按 C 语言头文件（include file）的风格将变量名大写。
.TP
.I \-d
以十进制而非十六进制显示偏移量。
.TP
.IR \-E " | " \-EBCDIC
将右侧列的字符编码从 ASCII 更改为 EBCDIC。
这不会改变十六进制表示。此选项与 \-r、\-p 或 \-i 组合使用时无效。
.TP
.IR \-e
切换到小端序十六进制转储。
此选项将字节组视为小端字节序的字。
默认的 4 字节分组可通过
.RI "" \-g
更改。
此选项仅适用于十六进制转储，保持 ASCII（或 EBCDIC）表示不变。
命令行开关 \-r、\-p、\-i 在此模式下无效。
.TP
.IR "\-g bytes " | " \-groupsize bytes"
每隔
.RI < bytes >
个字节（每个字节对应两位十六进制字符或八位比特数字）用空格分隔输出。
指定
.I \-g 0
可取消分组。
.RI < Bytes >
在普通模式下默认为 \fI2\fP，在小端模式下为 \fI4\fP，在比特模式下为 \fI1\fP。
分组不适用于 PostScript 或 C 语言头文件（include）样式。
.TP
.IR \-h " | " \-help
打印可用命令摘要并退出。不执行十六进制转储。
.TP
.IR \-i " | " \-include
按 C 语言头文件（include file）的风格输出。
通常写入完整的静态数组定义（以输入文件命名），从 stdin 读取时除外。
可与 -b 共用。
.TP
.IR "\-l len " | " \-len len"
写入
.RI < len >
个字节后停止。
.TP
.I "\-n name " | " \-name name"
当使用 \-i 时覆盖输出的变量名。数组命名为
\fIname\fP，长度命名为 \fIname\fP_len。
.TP
.I \-o offset
将
.RI < offset >
添加到显示的文件位置。
.TP
.IR \-p " | " \-ps " | " \-postscript " | " \-plain
以 PostScript 连续十六进制转储样式输出。也称为纯十六进制转储样式。
.TP
.IR \-r " | " \-revert
反向操作：将十六进制转储转换（或修补）为二进制。
如果不写入标准输出，xxd 写入输出文件时不截断文件。
使用
.I \-r \-p
组合可以读取没有行号信息且无特定列布局的纯十六进制转储。
允许任意位置的额外空格和换行符。
使用
.I \-r \-b
组合可以读取比特转储而非十六进制转储。
.TP
.IR \-R " " when
在输出中，十六进制值和 ASCII 值根据十六进制值使用相同颜色着色。
主要用于帮助区分可打印字符和不可打印字符。
.I \fIwhen\fP
可以是
.BR never 、 always  或  auto （默认: auto）。
当设置了
.BR $NO_COLOR
环境变量时，将禁用着色。
.TP
.I \-seek offset
当在
.IR \-r
之后使用时：还原时在十六进制转储中找到的文件位置上添加
.RI < offset >。
.TP
.I \-s [+][\-]seek
从
.RI < seek >
字节的绝对（或相对）输入文件偏移量处开始。
\fI+ \fR 表示偏移量相对于当前标准输入文件位置（不从标准输入读取时无效）。
\fI\- \fR 表示偏移量应从输入末尾向前计数多少字符（或与 \fI+\fR 组合时：在当前标准输入文件位置之前）。
如果不带 \-s 选项，xxd 从当前文件位置开始。
.TP
.I \-t
当使用 \-i 以 C 语言头文件（include file）的风格输出时，包含结尾的零字节。
.TP
.I \-u
使用大写十六进制字母。默认为小写。
.TP
.IR \-v " | " \-version
显示版本字符串。
.SH 注意事项
.PP
.I xxd \-r
在解析行号信息时具有一些内置的智能处理。
如果输出文件可寻址，则每个十六进制转储行开头的行号可能乱序、行可能缺失或重叠。
在这些情况下，xxd 会使用 lseek(2) 跳转到下一个位置。如果输出文件不可寻址，则只允许间隙，这些间隙将由空字节填充。
.PP
.I xxd \-r
从不生成解析错误。垃圾数据会被静默跳过。
.PP
编辑十六进制转储时，请注意
.I xxd \-r
在读取足够列数的十六进制数据后（参见 \-c 选项），会跳过输入行上的所有其他内容。
这也意味着对可打印 ASCII（或 EBCDIC）列的更改总是被忽略。
使用 xxd \-r \-p 还原纯十六进制转储（或 PostScript）样式时，不依赖于正确的列数。
在这种情况下，任何看起来像一对十六进制数字的内容都会被解释。
.PP
注意以下两者的区别：
.br
\fI% xxd \-i file\fR
.br
和
.br
\fI% xxd \-i < file\fR
.PP
.I xxd \-s +seek
可能与
.IR "xxd \-s seek"
不同，因为 lseek(2) 用于"回退"输入。
如果输入源是标准输入，并且在 xxd 启动并接收输入时标准输入的文件位置不在文件开头，那么 '+' 就会产生影响。
以下示例可能有助于澄清（或进一步混淆！）：
.PP
在读取前回退标准输入；因为 `cat` 已经读到了标准输入的末尾。
.br
\fI% sh \-c "cat > plain_copy; xxd \-s 0 > hex_copy" < file\fR
.PP
从文件位置 0x480（=1024+128）开始生成十六进制转储。
`+` 号表示"相对于当前位置"，因此 `128` 加到了 dd 停止的 1k 位置之后。
.br
\fI% sh \-c "dd of=plain_snippet bs=1k count=1; xxd \-s +128 > hex_snippet" < file\fR
.PP
从文件位置 0x100（=1024\-768）开始生成十六进制转储。
.br
\fI% sh \-c "dd of=plain_snippet bs=1k count=1; xxd \-s +\-768 > hex_snippet" < file\fR
.PP
然而，这种情况很少见，`+` 的使用通常并不需要。
作者建议在使用 \-s 时，用 strace(1) 或 truss(1) 监控 xxd 的效果。
.SH 示例
.PP
.br
打印
.BR file
除前三行（十六进制 0x30 字节）之外的所有内容。
.br
\fI% xxd \-s 0x30 file\fR
.PP
.br
从
.BR file
末尾开始打印 3 行（十六进制 0x30 字节）。
.br
\fI% xxd \-s \-0x30 file\fR
.PP
注意：以下示例的结果基于 2026 年 3 月的 xxd.1 手册页。
.PP
.br
打印 120 字节，以连续十六进制转储格式，每行 20 个字节。
.br
\fI% xxd \-l 120 \-ps \-c 20 xxd.1\fR
.br
2e544820585844203120224d6172203230323622
.br
20224d616e75616c207061676520666f72207878
.br
64220a2e5c220a2e5c222032317374204d617920
.br
313939360a2e5c22204d616e2070616765206175
.br
74686f723a0a2e5c2220202020546f6e79204e75
.br
67656e74203c746f6e79407363746e7567656e2e
.br

.br
将此手册页的前 120 字节以每行 12 个字节进行十六进制转储。
.br
\fI% xxd \-l 120 \-c 12 xxd.1\fR
.br
00000000: 2e54 4820 5858 4420 3120 224d  .TH XXD 1 "M
.br
0000000c: 6172 2032 3032 3622 2022 4d61  ar 2026" "Ma
.br
00000018: 6e75 616c 2070 6167 6520 666f  nual page fo
.br
00000024: 7220 7878 6422 0a2e 5c22 0a2e  r xxd"..\\"..
.br
00000030: 5c22 2032 3173 7420 4d61 7920  \\" 21st May
.br
0000003c: 3139 3936 0a2e 5c22 204d 616e  1996..\\" Man
.br
00000048: 2070 6167 6520 6175 7468 6f72   page author
.br
00000054: 3a0a 2e5c 2220 2020 2054 6f6e  :..\\"    Ton
.br
00000060: 7920 4e75 6765 6e74 203c 746f  y Nugent <to
.br
0000006c: 6e79 4073 6374 6e75 6765 6e2e  ny@sctnugen.
.PP
.br
仅显示文件 xxd.1 中的日期。
.br
\fI% xxd \-s 0x33 \-l 13 \-c 13 xxd.1\fR
.br
00000033: 3231 7374 204d 6179 2031 3939 36  21st May 1996
.PP
.br
将
.B input_file
复制到
.B output_file
并在开头添加 100 个值为 0x00 的字节。
.br
\fI% xxd input_file | xxd \-r \-s 100 > output_file\fR
.br

.br
修补文件 xxd.1 中的日期。
.br
\fI% echo "0000034: 3574 68" | xxd \-r \- xxd.1\fR
.br
\fI% xxd \-s 0x33 \-l 13 \-c 13 xxd.1\fR
.br
00000033: 3235 7468 204d 6179 2031 3939 36  25th May 1996
.PP
.br
创建一个 65537 字节的文件，所有字节均为 0x00，
除了最后一个字节是 'A'（十六进制 0x41）。
.br
\fI% echo "010000: 41" | xxd \-r > file\fR
.PP
.br
使用自动跳过模式对此文件进行十六进制转储。
.br
\fI% xxd \-a \-c 12 file\fR
.br
00000000: 0000 0000 0000 0000 0000 0000  ............
.br
*
.br
0000fffc: 0000 0000 41                   ....A
.PP
创建一个 1 字节的文件，包含单个字符 'A'。
在 '\-r \-s' 后面的数字会加到文件中找到的行号上；
实际效果是抵制了开头的字节。
.br
\fI% echo "010000: 41" | xxd \-r \-s \-0x10000 > file\fR
.PP
在编辑器（如
.B vim(1)
）中将 xxd 用作过滤器，对 `a` 和 `z` 之间的标记区域进行十六进制转储。
.br
\fI:'a,'z!xxd\fR
.PP
在编辑器（如
.B vim(1)
）中将 xxd 用作过滤器，恢复标记在 `a` 和 `z` 之间的二进制十六进制转储。
.br
\fI:'a,'z!xxd \-r\fR
.PP
在编辑器（如
.B vim(1)
）中将 xxd 用作过滤器，恢复一行十六进制转储。将光标移动到该行并键入：
.br
\fI!!xxd \-r\fR
.PP
从串行线读取单个字符。
.br
\fI% xxd \-c1 < /dev/term/b &\fR
.br
\fI% stty < /dev/term/b \-echo \-opost \-isig \-icanon min 1\fR
.br
\fI% echo \-n foo > /dev/term/b\fR
.PP
以 C 语言头文件（include）的风格输出，并包含结尾的零字节。
.br
\fI% echo -n \&"0123456789\&" > digits\fR
.br
\fI% xxd -i -t digits\fR
.br
unsigned char digits[] = {
.br
  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00
.br
};
.br
unsigned int digits_len = 10;
.PP
.SH "返回值"
返回以下错误值：
.TP
0
未遇到错误。
.TP
\-1
不支持的操作
\%(\c
.I \%xxd \-r \-i
仍不可用）。
.TP
1
解析选项时出错。
.TP
2
输入文件问题。
.TP
3
输出文件问题。
.TP
4,5
无法到达所需的查找位置。
.SH 另见
uuencode(1), uudecode(1), patch(1)
.br
.SH 警告
此工具的各种古怪特性与其创建者的大脑如出一辙。
使用风险完全自负。切记复制文件。梳理结构。终成大师。
.br
.SH 版本
此手册页记录的是 2024 年 5 月的 xxd 版本 1.7。
.SH 作者
.br
(c) 1990-1997 由 Juergen Weigert 编写
.br
<jnweiger@informatik.uni\-erlangen.de>
.LP
自由分发并保留我的署名，
.br
赚钱了请与我分享，
.br
亏钱了别来找我。
.PP
手册页由 Tony Nugent 创建
.br
<tony@sctnugen.ppp.gu.edu.au> <T.Nugent@sct.gu.edu.au>
.br
Bram Moolenaar 做了少量修改。
由 Juergen Weigert 编辑。
.PP
