Відповіді:
Ви можете спробувати:
%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, який інакше не міг бути відображений), ^
за яким не супроводжуються @
, тому ви не можете просто ввести ^
та @
рядок у вищевказаній команді.
Ця команда видаляє всі ^@
.
Я не думаю, що ваші файли пошкоджені. Ваш зразок рядка виглядає так, що він містить звичайний текст із нульовими байтами між кожним символом. Це говорить про те, що це текстовий файл, який закодований в 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 для перезавантаження файла з правильним кодуванням за допомогою команди:
:e ++enc=utf16
Це фактично працювало для мене в рамках vim:
:%s/\%x00//g
<Ctrl-V><Ctrl-2>
(як і той, з <Ctrl-Shift-2>
ким), але це спрацювало.
Як зазначали інші, це нульові байти (ASCII 00). В Linux спосіб введення значень ASCII у vim - це натиснення Ctrl-V з подальшим 3-розрядним восьмеричним значенням будь-якого символу. Щоб замінити всі нульові байти, використовуйте:
:%s/
Ctrl-V000//g
(без пробілів).
Так само ви можете шукати нулі за допомогою:
/
Ctrl-V000
В обох випадках він не відображатиме нулі, коли ви їх набираєте, але після введення всіх трьох він відобразиться ^@
. На кольорових терміналах буде показано, що синім кольором позначає, що це контрольний символ.
FWIW, в моєму випадку мені довелося використовувати vim на cygwin для редагування текстового файлу, створеного на mac. Прийняте рішення не працювало для мене, але було близько. Згідно сторінки вікі Віма про роботу з Unicode , існує різниця між Big Endian і Little Endian версіями байту BOM. Отже, мені довелося прямо сказати, vim
щоб використовувати Little Endian версію кодування BOM.
Лише після вибору потрібного кодування я перетворив формат файлу (закінчення рядків), щоб dos
я міг редагувати файл у редакторі Windows. Спроба встановити скинути формат файлу перед тим, як вказати кодування, принесла мені горе. Ось повний список команд, які я використав:
:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq
Прийняте рішення для мене не спрацювало. Я tr
замість цього зробив файл vim pipe :
:%!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'
^@
не поганий символ, якщо ви використовуєте правильне кодування, але якщо ви хочете видалити, спробуйте:
tr -d '\000'
sed 's/\000//g'
^ М символ є у ваших даних прикладу
Щоб конвертувати файл у формат Unix / Linux перед будь-якою обробкою, спробуйте:
dos2unix filename
- рель та ін
dos2ux filename [newfilename]
- HP-UX
Окрім відповіді @ jrb, у Vim кодування символів файлу виявляється на основі параметра fileencodings. (зверніть увагу на "s" в кінці fileencodings)
Тобто в Windows, значенням за замовчуванням для fileencodings
параметра є ucs-bom
, що означає:
перевірте, чи існує BOM на початку файлу.
Якщо BOM існує, тоді "прочитайте кодування символів з файлу BOM".
Якщо BOM не існує (і в цьому випадку це також означатиме, що всі кодування символів, визначені в fileencodings
опції, не відповідали), тоді прочитайте файл із кодуванням символів, вказаним у encoding
параметрі. Кодування символів за замовчуванням для encoding
опції: latin1
. Тепер, оскільки кодування символів довжиною latin1
в один байт , усі байти у файлі є дійсними latin1
символами (навіть Nul
символ, ^@
який ви бачите *).
* - насправді, ^@
це символ нового рядка в буфері Vim, а не символ Nul.
Правильним способом читання файлу є визначення кодування символів вручну як UTF-16 (так як схоже, що UTF-16 - це правильне кодування символів у цьому випадку).