使用 vim 按十六进制代码进行搜索

53
我需要清理一个文件。我们有一个运行在此文件上的 XML 解析器,由于文件中有转义字符(0x1B),因此它失败了。我该如何使用 vim 查找文件中该字符的位置,以便删除它?
示例文件:
<?php
echo "Hello, world.\n";                           
?>

转换后:

0000000: 0a3c 3f70 6870 0a65 6368 6f20 2248 656c  .<?php.echo "Hel
0000010: 6c6f 2c20 776f 726c 642e 5c6e 223b 0a3f  lo, world.\n";.?
0000020: 3e0a  

于是我删除了一个字符:(在这个例子中,是 'H')

0000000: 0a3c 3f70 6870 0a65 6368 6f20 22 656c  .<?php.echo "Hel
0000010: 6c6f 2c20 776f 726c 642e 5c6e 223b 0a3f  lo, world.\n";.?
0000020: 3e0a

注意第一行不再够宽了。当我将其转换回来时,我得到:

^@<?php
echo "el^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@> 
3个回答

74

搜索(例如使用/\%x1b

您还可以通过使用Ctrl-V将控制字符(包括转义)键入命令行。因此,请键入/Ctrl-VEscEnter


1
我不确定还需要多少细节。不要费心转换为十六进制表示。Vim将一个转义字符显示为^ [。使用我的任何一种方法搜索它,并将光标放在上面,使用x删除它。 - Nefrubyr
1
对于那些将<Ctrl-V>映射为“粘贴”的人(例如,在Windows gvim上默认设置):您需要将<Ctrl-Q>替换为<Ctrl-V>,以便使用控制字符执行相同的技巧。 - Chris
2
如果你正在寻找一个范围,可以这样做:/ [\x7f-\xff]。你也可以通过Unicode字符查找 /\u001d。 - Ryan Shillington
2
我发现,例如 / \%x1b,效果很好,但是我想问一下:的目的/含义是什么? - Craig Silver
这个能用来查找UTF-16字符吗? - Geremia
显示剩余4条评论

13
将vim转换成十六进制编辑器,方法是执行 [escape] :%!xxd 命令,然后搜索 0x1B(/1B)。

一旦我以那种模式打开它,我该如何删除那个字符并保存文件? - David Oneill
1
使用 h、j、k、l 导航到字符,按 'r' 并输入新字符。然后按 Esc,输入:wq 以退出并保存。 - Alexander Gessler
3
抱歉,你需要使用´:%!xxd -r´命令切换回ASCII编码后再保存。希望这样做可以解决问题。 - Alexander Gessler
为了允许删除/插入,我建议在转换和还原时都使用“-p”选项 - 这将关闭格式化。 - user85421
@CarlosHeuberger 是的,那可能有效,但会使查找1b更加困难:例如,您可能会在中间匹配到31 b7并再次破坏您的文件(当您的块长度为60个尼布尔时,而不是4个尼布尔时,这不容易)。 - Ruslan
显示剩余2条评论

4

您可以将光标放在字符上,然后按下 ga 来查看字符的十六进制值。

下面是一个 <╬> 字符的十六进制值示例:

<╬> <|N> 206, 十六进制值为 ce, 八进制值为 316, 数字为 I>

删除它的方法如下:

%s/\%xce//g 

1
需要注意的是,这不会显示文件中存储的物理字节,而是Unicode代码点。这是不同的。例如,对于德语字母Ä,它将显示Hex 00c4,它与Unicode中的U+00C4相关。要获取实际字节,可以使用g8,它会给出c3 84,这是文件中使用的Ä的实际UTF-8编码。 - Michael Härtl
如果是多字节字符,那么您需要使用%u或%U。请参见:h %u - nhooyr

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