在 Vim 中查看文件的十六进制格式,可以通过以下步骤实现:
方法 1:使用内置命令(无需插件)
-
用 Vim 以二进制模式打开文件:
bashvim -b 文件名
或打开文件后执行:
vim:set binary
-
转换为十六进制视图:
vim:%!xxd
- 这会调用
xxd
工具(Vim 自带)将二进制内容转为十六进制格式显示。
- 这会调用
-
返回正常模式(编辑后需转换回原始格式):
vim:%!xxd -r
方法 2:使用快捷键插件(推荐)
-
在
~/.vimrc
中添加配置 :vim" 按 <F4> 在十六进制/文本模式间切换 nnoremap <F4> :call ToggleHex()<CR> function! ToggleHex() if !exists("b:hex_mode") || !b:hex_mode :%!xxd let b:hex_mode = 1 else :%!xxd -r let b:hex_mode = 0 endif endfunction
- 保存后重启 Vim,打开文件后按
<F4>
即可切换视图。
- 保存后重启 Vim,打开文件后按
方法 3:使用专用插件(如 hexmode
)
-
安装插件 (通过插件管理器,如
vim-plug
):vimPlug 'fidian/hexmode'
-
使用命令切换视图:
vim:Hexmode " 进入十六进制模式 :Hexmode! " 返回文本模式
操作示例:
-
打开文件:
bashvim -b test.bin
-
执行
:%!xxd
后显示效果:00000000: 4865 6c6c 6f20 576f 726c 6421 0a Hello World!.
- 左侧 :字节偏移量(如
00000000
) - 中间:十六进制字节(每 2 字符为 1 字节)
- 右侧 :ASCII 可显示字符(
.
表示不可见字符)
- 左侧 :字节偏移量(如
-
编辑后需用
:%!xxd -r
转换回二进制再保存!
⚠️ 注意:直接修改十六进制内容可能破坏文件结构,建议操作前备份!
您的问题非常到位!%!xxd
确实是 Vim 中处理二进制/十六进制的核心技巧,让我详细解释这个命令的每个部分和工作原理:
%!xxd
命令分解:
-
%
- 范围标识符代表 整个文件 (从第一行到最后一行)。
Vim 中其他常用范围:
10,20
:第 10 行到第 20 行.
:当前行$
:最后一行
-
!
- 过滤器操作符表示 将选定文本通过外部命令过滤 (类似 Unix 的管道
|
)。 -
xxd
- 十六进制转换工具Vim 内置的二进制工具(Linux/macOS 系统也自带),专门用于:
- 将二进制 → 十六进制(
xxd
) - 将十六进制 → 二进制(
xxd -r
)
- 将二进制 → 十六进制(
执行流程:
Vim 缓冲区 %!xxd xxd 程序 转换后的十六进制数据 替换回 Vim 缓冲区
- Vim 将当前文件内容 作为标准输入 发送给
xxd
xxd
将接收到的二进制数据转换为十六进制格式xxd
的输出结果 替换 原文件内容
为什么必须用 !
而不用直接执行?
xxd
需要原始二进制输入
直接执行:!xxd
会启动新 shell 进程,无法获取 Vim 缓冲区内容!
实现了管道机制
相当于在终端执行:cat 当前文件 | xxd > 临时文件
,然后 Vim 加载该临时文件- 保持编辑状态
转换后直接在当前缓冲区操作,无需重新打开文件
关键注意事项:
-
二进制模式必须开启
执行前需先运行
:set binary
,否则 Vim 会自动转换换行符(LF ↔ CRLF),破坏二进制数据。 -
编辑后的还原
修改十六进制内容后,必须用
:%!xxd -r
转换回二进制格式再保存,否则文件将包含十六进制文本。 -
偏移量说明
xxd
生成的格式:00000000: 4865 6c6c 6f20 576f 726c 6421 0a Hello World!.
00000000
:字节偏移量(16进制)- 中间部分:每 2 字符代表 1 字节的十六进制值
- 右侧:ASCII 可视化表示(
.
表示不可打印字符)
类比理解:
Vim 命令 | 等效终端命令 | 功能 |
---|---|---|
:%!xxd |
`cat file | xxd` |
:%!xxd -r |
`cat file | xxd -r` |
:10,20!xxd |
`sed -n '10,20p' file | xxd` |
实际案例:
-
查看二进制文件:
vimvim -b demo.bin " 以二进制模式打开 :%!xxd " 转换为十六进制视图
-
修改并保存:
vim/4865 " 查找字节 48 65 (对应 "He") :s/4865/5945/g " 替换为 59 45 (变成 "Ye") :%!xxd -r " 转换回二进制 :wq " 保存退出
这样文件开头的 "Hello" 就被改成了 "Yello"。
理解了这个机制,您就掌握了 Vim 中处理二进制数据的核心能力!
您提出了一个非常关键的问题!直接使用 vim file
而不加 -b
参数是不安全的,原因如下:
为什么必须用 vim -b
或 :set binary
?
-
换行符自动转换问题:
- Vim 默认会根据系统环境自动转换换行符(如 LF ↔ CRLF)
- 二进制文件中的
0x0A
(LF) 和0x0D
(CR) 会被错误转换 - 结果:文件内容被破坏!
-
字符编码问题:
- Vim 会尝试用当前编码(如 UTF-8)解释二进制数据
- 可能导致非法字节序列被替换为
�
(U+FFFD)
-
文件结尾处理:
- Vim 默认会在文件末尾添加换行符(如果不存在)
- 二进制文件大小会被改变
对比实验(危险!请勿在生产环境尝试)
-
创建测试文件:
bashecho -ne "Hello\x00World\xff" > test.bin
-
错误方式打开:
bashvim test.bin # 不加 -b 参数
-
执行
:%!xxd
后可能看到:00000000: 4865 6c6c 6f00 576f 726c 64ff Hello.World.�
-
实际文件已被修改 :Vim 自动添加了换行符,
0xff
被显示为非法字符
-
-
正确方式打开:
bashvim -b test.bin
-
执行
:%!xxd
后:00000000: 4865 6c6c 6f00 576f 726c 64ff Hello.World.
-
文件内容保持原样
-
紧急补救方案
如果您已经用普通方式打开了二进制文件:
-
立即执行:
vim:set binary " 停止进一步破坏 :e! " 放弃修改重新加载
-
检查是否已损坏:
vim:!cmp original.bin % " 比较文件是否相同
-
如果已修改:
vim:q! " 不保存退出 vim -b file " 重新用二进制模式打开
为什么 :set binary
能解决问题?
这个命令会同时设置三个关键选项:
vim
:set binary " 等价于:
:set bin " 缩写
:set noeol " 不在文件末尾添加换行符
:set nofixeol " 不"修复"行尾
:set nobomb " 不添加UTF-8 BOM
:set textwidth=0
:set wrapmargin=0
:set encoding=latin1 " 使用单字节编码
最佳实践总结
操作 | 风险等级 | 推荐度 |
---|---|---|
vim -b file |
⚠️ 无风险 | ★★★★★ |
vim file + :set binary |
⚠️ 打开时可能有轻微风险 | ★★★☆☆ |
vim file 直接操作 |
☢️ 高风险 | ★☆☆☆☆ |
结论 :对于二进制文件,必须 使用 vim -b
或在打开后立即执行 :set binary
,否则文件可能被不可逆损坏!