Як замінити персонаж на новий рядок у Vim


1967

Я намагаюся замінити кожен ,у поточному файлі на новий рядок:

:%s/,/\n/g 

Але він вставляє те, що схоже на ^@замість фактичного нового рядка. Файл не знаходиться в режимі DOS або нічого подібного.

Що я повинен зробити?

Якщо ви цікаві, як я, перевірте питання Чому \ ra newline для Vim? так само.


2
Переповнення стека - це сайт для програмування та питань розробки. Це питання видається поза темою, оскільки мова не йде про програмування чи розробку. Дивіться, які теми я можу запитати тут, у довідковому центрі. Можливо, краще користуватися питаннями Super User або Unix & Linux Stack Exchange .
jww

5
@jww цьому питанню 10 років ... здається, занадто стара для міграції. Є багато питань , як це, наприклад: stackoverflow.com/questions/10175812 / ...
Вінко Vrsalovic

14
@jww vim - це інструмент, який зазвичай використовується для програмістів, а питання про інструменти, які зазвичай використовуються для програмістів, знаходяться на темі в розділі Переповнення стека . Хоча, очевидно, це більше підходить для Vi та Vim .
користувач202729

Відповіді:


2565

Використовуйте \rзамість \n.

Підстановка шляхом \nвставки нульового символу в текст. Щоб отримати новий рядок, використовуйте \r. Під час пошуку нової лінії ви все одно будете користуватися \n. Ця асиметрія пояснюється тим, що \nі \r роблять дещо інші речі :

\nвідповідає кінці рядка (нова лінія), тоді як \rвідповідає поверненню вагона. З іншого боку, заміни \nвставляє нульовий символ, тоді як \rвставляє новий рядок (точніше, це трактується як вхідний <CR>). Ось невеликий неінтерактивний приклад, щоб проілюструвати це, використовуючи функцію командного рядка Vim (іншими словами, ви можете скопіювати та вставити наступне в термінал, щоб запустити його). xxdпоказує шестнадцятковий файл отриманого файлу.

echo bar > test
(echo 'Before:'; xxd test) > output.txt
vim test '+s/b/\n/' '+s/a/\r/' +wq
(echo 'After:'; xxd test) >> output.txt
more output.txt
Before:
0000000: 6261 720a                                bar.
After:
0000000: 000a 720a                                ..r.

Іншими словами, \nвставив у текст байт 0x00; \rвставив байт 0x0a.


127
/ r трактується як натискання клавіші Enter / Return. Він працює на всіх платформах.
Лука Марінко


14
Я б хотів, щоб це працювало для класичного vi. У AIX v6.1 \rне працює так. Але ви можете натиснути Ctrl-V Enterзамість набору тексту \r, і це працює.
екзорцо

3
Я спізнююсь на вечірку. Якщо \rвставки <CR>та \nвставки нульові, як би я щось замінив поверненням каретки?
Містер Лама

2
@SunnyRaj Ви впевнені в історії CR та LF? У мене було враження, що спочатку LF перемістив папір на один ряд вперед, але не перемістив друкуючу головку, а CR перемістив друкуючу головку, але не перемістив папір. Як результат, якщо ваша ОС не перетворила вхід перед друком, ви не могли просто використовувати лише LF або CR, щоб отримати правильний вихід. MS DOS використовував необроблені дані принтера як формат текстового файлу, Mac OS використовував CR і перетворював з цього формат у необроблений принтер, а UNIX використовував LF і перетворював з цього у вихідний формат принтера.
Мікко Ранталайнен

210

Ось хитрість:

Спочатку встановіть свій Vi (m) сеанс, щоб дозволити узгодження шаблонів із спеціальними символами (тобто: новий рядок). Мабуть, варто ввести цей рядок у свій .vimrc або .exrc файл:

:set magic

Далі зробіть:

:s/,/,^M/g

Щоб отримати ^Mсимвол, введіть Ctrl+ Vі натисніть Enter. В операційній системі Windows, зробіть Ctrl+ Q, Enter. Єдиний спосіб, що я можу запам'ятати, це пам’ятати, як мало сенсу вони мають:

Відповідь: Що було б найгіршим контрольним символом для використання нового рядка?

Б: Або q(тому що це зазвичай означає "Вийти"), або vтому, що було б так просто набрати Ctrl+ Cпомилково і вбити редактора.

A: Зроби так.


9
Я використовую GVim у Windows, і мені не потрібно ні :set magic(це не в моєму ~ / _vimrc) або ctrl-q. Тільки простий, ctrl-vза яким вводиться enter, створює ^Mдля мене персонажа чудово.
Кріс Філіпс

5
Cv не представляє нового рядка; це команда "уникнути наступного буквального символу". Я не знаю, що Cv є мнемонічним для будь-якого, але є причина, що він подумки не відповідає новому рядку.
Джим Стюарт

27
Ctrl-v є мнемонічним для "дословно" - тобто втекти наступну клавішу, натиснуту на її "дослівний" код / ​​символ. У Windows це вставляти: тримати речі звичними. Ctrl-Q можливо для "(не) котирування", можливо. Досить дурний, у будь-якому випадку - але ви можете використовувати його у двійкових файлах - наприклад, для пошуку Ctrl-A через Ctrl-Z (Ascii 1-26, мабуть).
Томаш Гандор

1
Ctrl-Cнасправді не вбиває редактор, хоча він може скасувати вас у звичайному режимі. Ctrl-Vозначає дослівно, і Ctrl-Qозначає, що хтось допустив помилку при завантаженні $VIMRUNTIME/mswin.vimфайла конфігурації. Вам не потрібен mswin. Просто використовуйте власний vimrc замість цього.
00дані

вау ---- це дивовижно. Я раніше робив sed -n l . Добре знати, що те саме можна досягти і Ctrl-vв vim.
arpit

98

У синтаксисі s/foo/bar, \rі \nмають різні значення в залежності від контексту.


Короткий:

Для foo:

\ n = новий рядок (LF в Linux / Mac, CR + LF в Windows)
\ r = повернення каретки (CR)

Для bar:

\ r = - це новий рядок
\ n = нульовий байт.

Більш довгі (з номерами ASCII):

NUL= 0x00 = 0 = Ctrl+ @
LF= 0x0A = 10 = Ctrl+ J
CR= 0x0D = 13 = Ctrl+M

Ось список керуючих символів ASCII . Вставте їх у Vim через Ctrl+ V, Ctrl+ ---key---.

У Bash або інших оболонках Unix / Linux просто введіть Ctrl+ ---key---.

Спробуйте Ctrl+ Mв Bash. Це те саме, що натискання Enter, тому що оболонка розуміє, що мається на увазі, навіть якщо системи Linux використовують канали ліній для розмежування рядків.

Щоб вставити літерали в bash, попередньо додавши їх до Ctrl+ Vтакож буде працювати.

Спробуйте в Bash:

echo ^[[33;1mcolored.^[[0mnot colored.

Для цього використовуються послідовності відходу ANSI . Вставте два ^[«S з допомогою Ctrl+ V, Esc.

Ви також можете спробувати Ctrl+ V, Ctrl+ M, Enter, що дасть вам:

bash: $'\r': command not found

Пам'ятаєте \rзверху? :>

Цей список символів управління ASCII відрізняється від повної таблиці символів ASCII тим , що в ньому можна знайти контрольні символи, які вставляються в консоль / псевдотермінал / Vim за допомогою Ctrlключа (ха-ха).

Тоді як на C та більшості інших мов ви зазвичай використовуєте восьмеричні коди для представлення цих "символів".

Якщо ви дійсно хочете знати, звідки це все: TTY демістифікований . Це найкраще посилання, з яким ви натрапите на цю тему, але будьте уважні: є дракони.


TL; DR

Зазвичай foo= \n, і bar= \r.


1
Тож мене заінтригує, як ти
заміниш

2
@codeshot :s/x/^M/gповинен зробити. Вставте вікно, ^Mза ctrl-vяким слід ctrl-m.
sjas

3
Дякую sjas, Ви знаєте, що це питання є одним з найдивовижніших за всі часи. 1008 голосів за відповідь, яка в основному говорить не що інше, як "vim робить те, що ви знайшли. Це тому, що vim робить те, що ви знайшли. Ніколи не забувайте, що vim робить те, що ви знайшли". Я сподівався знайти шорт-лист кодів для цікавих символів у малюнку, заміну та причину дивацтва, тому його легко запам'ятати та передбачити інші подібні дивацтва. Це отримало б мій голос.
codehot

@codeshot список контрольних символів ascii може допомогти вам. Див. Cs.tut.fi/~jkorpela/chars/c0.html для подальшого ознайомлення. Я оновлю свою відповідь, щоб включити два посилання.
sjas

55

Вам потрібно використовувати:

:%s/,/^M/g

Щоб отримати ^Mсимвол, натисніть Ctrl+, vа потім - Enter.


4
Я повинен зробити <Cv> <Cm>, щоб отримати ^ М-символ.
Єзен Томас


24

Для Vim у Windows використовуйте Ctrl+ Qзамість Ctrl+ V.


16

Це найкраща відповідь на те, як я думаю, але було б приємніше в таблиці:

Чому \ ra новий рядок для Vim?

Отже, переформулювання:

Вам потрібно використовувати \rканал стрічки (ASCII 0x0A, новий рядок Unix) для заміни регулярних виразів, але це властиво заміні - зазвичай слід продовжувати використовувати \nдля подачі рядків та \rдля повернення вагона.

Це пояснюється тим, що Vim використовується \nв якості заміни для позначення символу NIL (ASCII 0x00). Можливо, ви очікували, що NIL \0замість цього звільнить \nйого для звичайного використання для подачі рядків, але \0вже має значення в замінах регулярних виразів, тому його перенесли на \n. Отже, далі ми також переходимо з нового рядка \nна \r(що в схемі регулярних виразів є символом повернення каретки, ASCII 0x0D).

Характер | ASCII код | C представлення | Регекс матч | Заміна Regex
------------------------- + ------------ + ----------- ------- + ------------- + ------------------------
нуль | 0x00 | \ 0 | \ 0 | \ n
стрічка лінії (новий рядок Unix) | 0x0a | \ n | \ n | \ r
повернення вагона | 0x0d | \ r | \ r | <невідомо>

Примітка: ^M( Ctrl+ V Ctrl+ Mв Linux) вставляє нову рядок, коли вона використовується для заміни регулярних виразів, а не повернення каретки, як радили інші (я просто спробував це).

Також зауважте, що Vim перекладе символ подачі рядка, коли він збереже файл у відповідності з його параметрами формату файлу, і це може заплутати питання.



8

Але якщо доводиться підміняти, то працює наступне:

:%s/\n/\r\|\-\r/g

У вищесказаному кожен наступний рядок замінюється наступним рядком, а потім |-і знову новим рядком. Це використовується у вікі-таблицях.

Якщо текст такий:

line1
line2
line3

Це змінено на

line1
|-
line2
|-
line3

7

Якщо вам потрібно зробити це для цілого файлу, мені також запропонували спробувати скористатися командним рядком:

sed 's/\\n/\n/g' file > newfile

1
Зауважте, що для цього потрібно GNU sed. Спробуйте printf 'foo\\nbar\n' | sed 's/\\n/\n/g'перевірити, чи буде він працювати у вашій системі. (Подяка хорошим людям #bash on freenode за цю пропозицію.)
Еван Донован,

Так, але питання стосувалося Віма. Виникає питання переповнення стека Як я можу замінити новий рядок (\ n) за допомогою sed? .
Пітер Мортенсен

5

Ось відповідь, яка працювала на мене. Від цього хлопця:

---- цитування Використовуйте редактор vi, щоб вставити новий знак символу на заміну


Щось ще я маю робити і не можу згадати, а потім треба шукати.

In vi, щоб вставити символ нового рядка в пошук і замінити, виконайте наступне:

:%s/look_for/replace_with^M/g

Команда, наведена вище, замінить усі екземпляри "look_for" на "substitu_with \ n" (з \ n означає новий рядок).

Щоб отримати "^ M", введіть комбінацію клавіш Ctrl+ V, а потім після цього (відпустіть усі клавіші) натисніть Enterклавішу.


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