Как заменить символ новой строкой в ​​Vim - PullRequest
1767 голосов
/ 16 сентября 2008

Я пытаюсь заменить каждый , в текущем файле новой строкой:

:%s/,/\n/g 

Но он вставляет то, что выглядит как ^@ вместо фактического перевода строки. Файл не в режиме DOS или что-либо еще.

Что мне делать?

Если вам любопытно, как и мне, проверьте вопрос Почему новая строка для Vim? также.

Ответы [ 11 ]

2305 голосов
/ 16 сентября 2008

Используйте \r вместо \n.

Подстановка \n вставляет нулевой символ в текст. Чтобы получить новую строку, используйте \r. Когда ищет новую строку, вы все равно используете \n. Эта асимметрия связана с тем, что \n и \r делают немного разные вещи :

\n соответствует концу строки (новая строка), тогда как \r соответствует возврату каретки. С другой стороны, в подстановках \n вставляет нулевой символ, тогда как \r вставляет новую строку (точнее, он обрабатывается как ввод ). Вот небольшой неинтерактивный пример, чтобы проиллюстрировать это, используя функцию командной строки Vim (другими словами, вы можете скопировать и вставить следующее в терминал, чтобы запустить его). xxd показывает hexdump полученного файла.

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.

184 голосов
/ 26 сентября 2008

Вот трюк:

Сначала установите сеанс vi (m), чтобы разрешить сопоставление с шаблоном со специальными символами (например, символом новой строки). Вероятно, стоит поместить эту строку в ваш файл .vimrc или .exrc.

:set magic

Далее выполните:

:s/,/,^M/g

Чтобы получить символ ^M, введите Control - v и нажмите Введите . В Windows выполните Control - q , Введите . Единственный способ, которым я могу вспомнить это, вспоминая, как мало они имеют смысла:

A: Какой контрольный символ был бы наихудшим для представления новой строки?

B: Либо q (потому что это обычно означает "Выход"), либо v, потому что было бы так просто набрать Control - c по ошибке и убейте редактора.

A: Сделать так.

84 голосов
/ 23 сентября 2013

В синтаксисе s/foo/bar \r и \n имеют разные значения в зависимости от контекста.


короткий:

Для foo:
\ n = новая строка (LF в Linux / Mac, CRLF в 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 --- ключ --- .
В bash или других оболочках Unix / Linux просто наберите CTRL --- ключ --- . Попробуйте CTRL M в bash, это то же самое, что нажать ENTER , поскольку оболочка понимает, что имеется в виду, даже если в системах Linux используется Line Feeds для разграничения строк.

Для вставки литералов в bash, предварение их с помощью CTRL v также будет работать.

Попробуйте в bash:

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

Используется escape-последовательности ANSI , вставьте два ^[ через CTRL v ESC .

Вы также можете попробовать CTRL v CTRL m ENTER , который даст вам следующее:

bash: $'\r': command not found

Помните \r сверху? :>

Этот Список управляющих символов ASCII отличается от полной таблицы символов ASCII тем, что управляющие символы, которые вставляются в консоль / псевдотерминал / vim через Клавиша CTRL (ха-ха), можно найти там. В то время как в C и большинстве других языков вы обычно используете восьмеричные коды для представления этих «символов».

Если вы действительно хотите знать, откуда все это происходит: http://www.linusakesson.net/programming/tty/.
Это лучшая ссылка на эту тему, с которой вы столкнетесь, но будьте осторожны: там будут драконы.


TL; DR

Обычно foo = \n и bar = \r.

50 голосов
/ 16 сентября 2008

Вам нужно использовать

:%s/,/^M/g

Чтобы получить символ ^M, нажмите Ctrl v , а затем Введите

33 голосов
/ 16 сентября 2008

\r может сделать работу здесь за вас.

22 голосов
/ 16 сентября 2008

С Vim в Windows используйте Ctrl + Q вместо Ctrl + V

10 голосов
/ 08 апреля 2015

Это лучший ответ на мой взгляд, но в таблице это было бы лучше: https://stackoverflow.com/a/12389839/962394.

Итак, формулировка:

Вам нужно использовать \r, чтобы использовать замену строки (ascii 0x0a, новая строка unix) в замене регулярных выражений, но это характерно для замены - обычно вы должны продолжать использовать \n для строки подача и \r для возврата каретки.

Это потому, что vim использовал \n в качестве замены для обозначения символа NIL (ascii 0x00). Возможно, вы ожидали, что вместо этого вместо NIL будет \0, что освободит \n для обычного использования для перевода строки, но \0 уже имеет значение в заменах регулярных выражений, поэтому оно было смещено на \n. Следовательно, затем идем дальше, чтобы также переместить новую строку с \n на \r (которая в шаблоне регулярного выражения является символом возврата каретки, ascii 0x0d).

character                | ascii code | C representation | regex match | regex replacement
-------------------------+------------+------------------+-------------+------------------------
nil                      | 0x00       | \0               | \0          | \n
line feed (unix newline) | 0x0a       | \n               | \n          | \r
carriage return          | 0x0d       | \r               | \r          | <unknown>

NB: ^M (Ctrl-V Ctrl-M в linux) вставляет новую строку при использовании в замене регулярного выражения вместо возврата каретки, как советуют другие (я только что попробовал).

Также обратите внимание, что vim будет переводить символ перевода строки при сохранении в файл в соответствии с настройками формата файла, что может привести к путанице.

10 голосов
/ 06 сентября 2011

Из затмения символы ^M могут быть встроены в строку, и вы хотите преобразовать их в новые строки.

:s/\r/\r/g
7 голосов
/ 07 февраля 2012

Но если нужно заменить, тогда действует следующее

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

в приведенном выше примере каждая следующая строка заменяется следующей строкой, затем | - и снова следующей строкой Это используется в вики-таблицах. если текст выглядит следующим образом:

line1
line2
line3

изменено на

line1
|-
line2
|-
line3
6 голосов
/ 10 февраля 2012

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

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