Как убрать этот символ «^ @» с vim?


59

У меня есть некоторые файлы, которые повреждены с этим символом:

^ @

Это не часть строки; это не для поиска. Как заменить этот символ ничем или как удалить этот символ?

Вот пример строки из одного файла:

^@F^@i^@l^@e^@n^@a^@m^@e^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@:^@ ^@^M^@

Ответы:


51

Вы можете попробовать:

  • %s/<CTRL-2>//g (на обычных ПК)

  • %s/<CTRL-SHIFT-2>//g (на компьютерах Mac)

где <CTRL-2>означает сначала нажать CTRLна обычные ПК, удерживая его нажатым, ударить 2, отпустить CTRL.

и <CTRL-SHIFT-2>означает сначала нажать controlна ПК Mac, удерживая его нажатым, нажать shiftна ПК Mac, удерживая его нажатым, нажать 2, отпустить controlи shift.

Наконец, обе команды должны появиться %s/^@//gна экране. ^@означает один символ (байт NULL, который иначе не может быть отображен), ^за которым не следует @, поэтому вы не можете просто набрать ^и @в строке в приведенной выше команде.

Эта команда удаляет все ^@.


4
Просто наткнулся на этот вопрос / ответ по соответствующей ссылке: на самом деле это плохой совет, и он будет работать должным образом только в очень немногих случаях. Лучше на самом деле изменить кодировку, чем удалять нулевые байты. Если вы удалите нулевые байты, у вас могут остаться другие многобайтовые символы, которые отображаются как мусор.
Марио

@ Марио, не могли бы вы рассказать нам больше об изменении кодировки? Это как-то связано с ответом JRB ниже?
Джордж

Смотрите ответ РПыж ниже. Показывает загрузку файла с использованием правильной кодировки, а также сохранение его с другой (хотя для ответа может потребоваться более подробное объяснение). Последнее примечание Jrb достаточно, если вы просто хотите прочитать его, но не если вы хотите сохранить его без нулевых байтов с использованием другой кодировки.
Mario

50

Я не думаю, что ваши файлы повреждены. Ваша строка примера выглядит так, как будто она содержит обычный текст с нулевыми байтами между каждым символом. Это говорит о том, что это текстовый файл, который был закодирован в UTF-16, но в начале файла отсутствует метка порядка байтов. Смотрите http://en.wikipedia.org/wiki/Byte-order_mark

Предположим, я открываю Блокнот, набираю слово «имя файла» и сохраняю как Unicode Big-endian. Шестнадцатеричный дамп этого файла выглядит так:

fe ff 00 66 00 69 00 6c 00 65 00 6e 00 61 00 6d 00 65

Если я открываю этот файл в Vim, он выглядит нормально - байты 'fe ff' сообщают Vim, как файл закодирован. Теперь предположим, что я создаю файл, содержащий точно такую ​​же последовательность байтов, но без начального 'fe ff'. Vim вставляет ^ @ (или <00>, в зависимости от вашей конфигурации) вместо нулевых байтов; Блокнот вставляет пробелы.

Поэтому вместо того, чтобы удалять нули, вам действительно нужно, чтобы Vim правильно интерпретировал файл. Вы можете заставить Vim перезагрузить файл с правильной кодировкой с помощью команды:

:e ++enc=utf16


Да, последняя команда заставила vim правильно интерпретировать файл, но не удаляет нуль-байты.
mrt181

6
Чтобы удалить их, выберите другую кодировку и снова сохраните файл:: set fenc = utf-8
scy

35

Это на самом деле работает для меня в VIM:

:%s/\%x00//g

5
это работает с подстановкой (), а Ctl-VCtl-Shift-2 - нет.
dsummersl

Та же самая проблема для меня, я не мог заставить <Ctrl-V><Ctrl-2>(так же как тот с <Ctrl-Shift-2>) работать, но это работало.
Джефф Б.

5
Это работает для меня Linux. '00' - это шестнадцатеричное значение ASCII, которое вы можете найти для любого символа в vim, наведя на него курсор и введя 'ga' (think "get ascii) в командном режиме или: as /: ascii в командной строке. Vim .wikia.com / wiki /…
Кейси Джонс,

^ Vx00 тоже работает. Вы также можете ввести 16-битный юникод с помощью ^ VuXXXX. Я попытался \% uXXXX в поиске, и это тоже сработало.
Эдвард Фальк

Ты будешь моим любимым мужчиной до конца времен. Из глубины моего сердца ... спасибо!
Гонсало Цао

12

Этот символ представляет собой символ NULL со значением ASCII 000.

С vim удалить сложно, попробуйте

tr -d '\000' < file1 > file2

7

Как уже отмечали другие, это нулевые байты (ASCII 00). В Linux способ ввода значений ASCII в vim состоит в том, чтобы нажать Ctrl-V, а затем восьмеричное восьмизначное значение любого символа. Чтобы заменить все нулевые байты, используйте:

    :%s/Ctrl-V000//g

(без пробелов).

Аналогично, вы можете искать нули с помощью:

    /Ctrl-V000

В обоих случаях он не будет показывать нули при их наборе, но после ввода всех трех он будет отображаться ^@. На цветных терминалах это будет показано синим цветом, чтобы указать, что это контрольный символ.


6

FWIW, в моем случае мне пришлось использовать vim на cygwin для редактирования текстового файла, созданного на Mac. Принятое решение не сработало для меня, но было близко. Согласно вики-странице Vim о работе с Unicode , существует разница между версиями байта BOM с Big Endian и Little Endian. Итак, я должен был явно сказать, vimчтобы использовать версию кодирования спецификации Little Endian.

Только после выбора правильной кодировки я преобразовал формат файла (окончания строк), dosчтобы я мог редактировать файл в редакторе Windows. Попытка установить сброс формата файла перед указанием кодировки меня огорчила. Вот полный список команд, которые я использовал:

:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq

Ценная информация. В моем случае это был порядок байтов спецификации.
Андре Альбукерке

3

Принятое решение не сработало для меня. Я сделал VIM трубу через файл tr:

:%!tr -d '\000'

Это также будет хорошо работать с визуальным режимом (просто печатать :!tr -d '\000') или рядом строк:

# Remove nulls from current line:
:.!tr -d '\000'

# Remove nulls from lines 3-5:
:3,5!tr -d '\000'

2

^@ Неплохой символ, если вы используете правильную кодировку, но если вы хотите удалить, попробуйте:

  • tr -d '\000'
  • sed 's/\000//g'

Символ ^ M есть в данных вашего примера

Чтобы преобразовать файл в формат Unix / Linux перед любой обработкой, попробуйте:

dos2unix filename - Рел и другие

dos2ux filename [newfilename] - HP-UX


1

В дополнение к ответу @ jrb в Vim определяется кодировка символов файла на основе опции fileencodings. (обратите внимание на 's' в конце кодирования файла)

Т.е. в Windows значением по умолчанию для этой fileencodingsопции является ucs-bom:

проверьте, существует ли спецификация в начале файла.

Если спецификация существует, тогда «прочитайте кодировку символов файла из спецификации».

Если спецификация не существует (и в этом случае это также будет означать, что все кодировки символов, указанные в fileencodingsпараметре, не совпадают), считайте файл с кодировкой символов, указанной в encodingпараметре. Кодировка символов по умолчанию для encodingопции: latin1. Теперь, поскольку latin1это кодировка символов длиной в один байт , все байты в файле являются допустимыми latin1символами (даже Nulсимвол, ^@который вы видите *).

* - фактически, ^@это символ новой строки в тексте буфера Vim, а не символ Nul.

Правильный способ чтения файла - указать кодировку символов вручную как UTF-16 (в этом случае UTF-16 выглядит как правильная кодировка символов).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.