8

当我在 bash 中查找文件时,我得到以下信息:

$ cat /tmp/file 
microsoft

当我在 vim 中查看相同的文件时,我得到以下信息:

^@m^@i^@c^@r^@o^@s^@o^@f^@t^@

如何识别和删除这些“不可打印”字符。'^@' 在 vi​​m 中是什么意思?

(只是一个背景信息:该文件是通过 base 64 解码和从 Microsoft Playready 的 mpd 文件的 pssh 标头切割创建的)

4

2 回答 2

7

你看到的是 Vim 对不可打印字符的可视化表示。它在以下位置进行了解释:help 'isprint'

Non-printable characters are displayed with two characters:
    0 -  31   "^@" - "^_"
   32 - 126   always single characters
     127      "^?"
  128 - 159   "~@" - "~_"
  160 - 254   "| " - "|~"
     255      "~?"

因此,^@代表空字节= 0x00。这些(和其他不可打印的字符)可以来自各种来源,但在你的情况下,它是一个......

编码问题

如果您在 Vim 中清楚地观察到您的输出,则每隔一个字节就是一个空字节;中间是预期的字符。这清楚地表明该文件使用了多字节编码utf-16准确地说是大字节序,没有字节顺序标记),而 Vim 没有正确检测到这一点,而是以大约的方式打开文件latin1(而在终端)。

要解决此问题,您可以显式指定编码:

:edit ++enc=utf-16 /tmp/file

或者调整'fileencodings'选项,以便 Vim 可以自动检测到这一点。但是,请注意,歧义(如您的情况)使这容易失败:

对于空文件或只有 ASCII 字符的文件,大多数编码都可以使用,并且将使用“fileencodings”的第一个条目(“ucs-bom”除外,它需要 BOM 存在)。

这就是为什么建议对 16 位编码使用字节顺序标记(BOM) 的原因;但这假设您可以控制输出编码。

于 2017-11-23T14:31:03.627 回答
4

^@是 Vim 对空字节的表示。表示不可打印的^控制字符,后面的 ASCII 字符表示它是哪个控制字符。

^@ == 0 (NUL)
^A == 1
^B == 2
...
^H == 8
^K == 11
...
^Z == 26
^[ == 27
^\ == 28
^] == 29
^^ == 30
^_ == 31
^? == 127

9 和 10 没有被转义,因为它们分别是 Tab 和 Line Feed。

32 到 126 是可打印的 ASCII 字符(以空格开头)。

于 2017-11-23T14:04:07.453 回答