Что означает "^@" в vim?

Когда я котирую файл в bash, я получаю следующее:

$ cat /tmp/file 
microsoft

Когда я просматриваю тот же файл в VIM, я получаю следующее:

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

Как я могу идентифицировать и удалить этих "непечатных" символов. Что означает "^@" в vim??

(Просто часть справочной информации: файл был создан с помощью декодирования base 64 и вырезания из заголовка pssh файла mpd для Microsoft Playready)

2 ответа

Решение

То, что вы видите, является визуальным представлением 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, big endian, без метки порядка байтов, если быть точным), и Vim не обнаружил это должным образом и вместо этого открыл файл как latin1 или около того (тогда как в терминале все работало правильно).

Чтобы это исправить, вы можете явно указать кодировку:

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

Или настроить 'fileencodings' опция, так что Vim может автоматически обнаружить это. Однако помните, что неоднозначности (как в вашем случае) делают это склонным к сбою:

Для пустого файла или файла, содержащего только символы ASCII, большинство кодировок будет работать, и будет использоваться первая запись 'fileencodings' (кроме "ucs-bom", которая требует наличия спецификации).

Вот почему метка порядка байтов (BOM) рекомендуется для 16-битных кодировок; но это предполагает, что у вас есть контроль над выходной кодировкой.

^@ является представлением 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 (начиная с пробела).

Другие вопросы по тегам