当我在 bash 中查找文件时,我得到以下信息:
$ cat /tmp/file
microsoft
当我在 vim 中查看相同的文件时,我得到以下信息:
^@m^@i^@c^@r^@o^@s^@o^@f^@t^@
如何识别和删除这些“不可打印”字符。'^@' 在 vim 中是什么意思?
(只是一个背景信息:该文件是通过 base 64 解码和从 Microsoft Playready 的 mpd 文件的 pssh 标头切割创建的)
你看到的是 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) 的原因;但这假设您可以控制输出编码。
^@
是 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 字符(以空格开头)。