52

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

^ @

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

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

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

9 ответов9

48

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

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

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

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

и <CTRL-SHIFT-2> означает, что сначала нажмите на элемент управления на компьютерах Mac, удерживая его нажатым, нажмите на клавишу Shift на компьютерах Mac, удерживая его нажатым, нажмите 2, отпустите элемент управления и сдвиньте.

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

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

47

Я не думаю, что ваши файлы повреждены. Ваша строка примера выглядит так, как будто она содержит обычный текст с нулевыми байтами между каждым символом. Это говорит о том, что это текстовый файл, который был закодирован в 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

31

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

:%s/\%x00//g
11

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

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

tr -d '\000' < file1 > file2
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
6

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

    :%s/ Ctrl-V 000//g

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

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

    / Ctrl-V 000

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

3

Принятое решение не сработало для меня. Я сделал vim pipe файл через 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 - rhel и другие

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 выглядит как правильная кодировка символов).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .