Як видалити цей символ "^ @" за допомогою 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
Просто натрапили на це питання / відповідь через пов’язане посилання: Це насправді погана порада, і вона справно працює лише в дуже небагатьох випадках. Краще насправді змінити кодування, а не видаляти нульові байти. Якщо ви видалите нульові байти, у вас можуть залишитися інші багатобайтові символи, які відображаються як сміття.
Mario Mario

@Mario, ти можеш розповісти більше про зміну кодування? Це щось пов’язане з відповіддю jrb нижче?
Джордж

Відповідь rpyzh див. Нижче нижче. Показує завантаження файлу за допомогою правильного кодування, а також збереження його за допомогою іншого (хоча для відповіді може знадобитися додаткове пояснення). Останньої примітки Jrb достатньо, якщо ви просто хочете її прочитати, але не, якщо ви хочете зберегти її без нульових байтів, використовуючи інше кодування.
Маріо

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 для перезавантаження файла з правильним кодуванням за допомогою команди:

:e ++enc=utf16


Так, остання команда vim інтерпретує файл правильно, але не видаляє нульбайти.
mrt181

6
Щоб видалити їх, виберіть інше кодування та збережіть файл ще раз:: встановіть 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» (подумайте «отримати 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 з подальшим 3-розрядним восьмеричним значенням будь-якого символу. Щоб замінити всі нульові байти, використовуйте:

    :%s/Ctrl-V000//g

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

Так само ви можете шукати нулі за допомогою:

    /Ctrl-V000

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


6

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

Дорога інформація. У моєму випадку це була витримка байту BOM.
Андре Альбукерке

3

Прийняте рішення для мене не спрацювало. Я 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'

2

^@ не поганий символ, якщо ви використовуєте правильне кодування, але якщо ви хочете видалити, спробуйте:

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

^ М символ є у ваших даних прикладу

Щоб конвертувати файл у формат Unix / Linux перед будь-якою обробкою, спробуйте:

dos2unix filename - рель та ін

dos2ux filename [newfilename] - HP-UX


1

Окрім відповіді @ 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 - це правильне кодування символів у цьому випадку).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.