在vim中跳转到字节地址?

49

我正在调查一个主要使用UTF-8编码的文件,其中有很多长行。但是,该文件并非完全是文本文件,其中还包含一些无用信息。为了找到我的兴趣点,我正在使用hdgrep工具。

因此,当我知道自己对0000301a感兴趣时,我想快速在Vim中打开文件并跳转到那个位置。

例如(这实际上是一个很小的文件,这里的位置是0000001c):

me@here:~$ hd file | grep -C 10 \ 00\ 
00000000  6c 69 6e 65 31 0a 6c 69  6e 65 32 0a 6c 69 6e 65  |line1.line2.line|
00000010  33 0a 6c 69 6e 65 34 0a  6c 69 6e 65 00 35 0a 6c  |3.line4.line.5.l|
00000020  69 6e 65 36 0a 6c 69 6e  65 37 0a 6c 69 6e 65 38  |ine6.line7.line8|
00000030  0a 6c 69 6e 65 39 0a 6c  69 6e 65 31 30 0a        |.line9.line10.|
0000003e
me@here:~$ 

Vim中有没有技巧可以跳转到字节位置?或尽可能接近它?


不确定这是否适用于您的情况,但您是否尝试将偏移量转换为十进制,然后使用 :goto 1234 - Kyle G.
1
顺便说一下,您不必使用十六进制编号,可以按任何您想要的方式格式化hd输出。请查看man页面。 - glts
3个回答

70

是的,有一个正常模式下的命令go可以使用。

:h go中得知:

[count]go         跳到缓冲区的第{count}个字节。

例如,42go会跳转到第42个字节。

如果要跳到一个十六进制或八进制地址,则需要构建一个带有:normal! go或等效的:goto命令,并且使用str2nr()printf()函数。

:exe 'normal! ' . str2nr('0x2a', 16) . 'go'
:exe 'goto' str2nr('0x2a', 16)

8
注意:Vim中的字节位置是以1为基础的(与列号和行号相同),而不是以0为基础的。 - Oberon

6
虽然这个问题本身有其价值,但我可以建议您使用更为直接的方式,只使用Vim完成整个过程,而不需要使用所有的hd、grep和shell。
关键在于 :h 23.4,“二进制文件”:Vim可以成为您的十六进制编辑器。
在使用 vim -b myfile 启动Vim并打开您的文件后,工作流程如下:
:%!xxd -g1<Enter>
/00 <Enter>
...
...
:%!xxd -r<Enter>

请务必阅读:h hex-editing,以获取更多详细信息。


3
是的,使用:help starting.txt,您可以找到有关所有vim命令行参数的帮助信息。
使用上面给出的转到命令,您应该能够从命令行向vim发送一个命令,以前往字节偏移量,例如: vim "+exe 'goto' str2nr('0x2a', 16)" file :help +byte_offset中有一个编译时间标志可以使用:ve命令进行检查。我的Ubuntu版本默认已经编译了此标志。

1
使用命令 vim --version | grep byte_offset 并查找 +- 通常比扫描 :version 更快。 - FDinoff
2
虽然 :echo has("byte_offset") 更快,但只需检查输出是否为 1 即可。 - FDinoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接