vim 中的“^@”是什么意思?

What does '^@' mean in vim?

当我在 bash 中 cat 一个文件时,我得到以下信息:

$ cat /tmp/file 
microsoft

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

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

如何识别和删除这些 "non-printable" 个字符。 vim 中的“^@”是什么意思??

(仅提供一条背景信息:该文件是通过 base 64 解码并从 Microsoft Playready 的 mpd 文件的 pssh header 剪切创建的)

^@ 是 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 字符(以 Space 开头)。

您看到的是 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 可以自动检测到它。但是,请注意,歧义(如您的情况)使这容易失败:

For an empty file or a file with only ASCII characters most encodings will work and the first entry of 'fileencodings' will be used (except "ucs-bom", which requires the BOM to be present).

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