Vim - как заменить одну новую строку \ n двумя \ n

34

В редакторе vim я хочу заменить символ новой строки (\ n) двумя символами новой строки (\ n \ n) в командном режиме vim.

Содержание входного файла:

This is my first line.
This is second line.

Команда, которую я попробовал:

:%s/\n/\n\n/g

он заменяет строку нежелательными символами как

This is my first line.^@^@This is second line.^@^@

Затем я попробовал следующую команду

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

Это работает правильно. Можете ли вы объяснить, почему он работает нормально со второй командой?

Raghvendra
источник
См. Также unix.stackexchange.com/a/206404
Стефан
2
К вашему сведению: есть также Vi и Vim (бета) SE .
Дабу
2
Примечание: вам не нужно использовать /в качестве разделителя. Это более читабельно::%s;\n;\n\n;g
DJMcMayhem
1
Поиск \n, заменить \r\r, :% s/\n/\r\r/g: stackoverflow.com/a/71334/911945
Антон Тарасенко

Ответы:

47

Как ни странно, \nв vim для замены подразумевается не перевод строки, а null. ASCII nul is ^@( control@).

Исторически vi заменяет ^M( controlM) как конец строки, то есть перевод строки. vim добавил расширение \r(например, язык C), чтобы оно означало то же, что и ^M, но разработчики решили сделать \nзначение NULL при замене текста. Это несовместимо с его использованием в поисках , которые находят новую строку.

Дальнейшее чтение:

Томас Дики
источник
7

Попробуйте это: %s/$/^V^M/(где ^Vесть Ctrl-Vи ^Mесть Ctrl-M- когда вы набираете, ^Vон печатает ^символ, затем возвращается на него, а затем, когда вы набираете, ^Mон будет выглядеть как ^M... Ctrl-V - это стандартный следующий буквенный символ tty - выполните команду stty -aдля показать специальные символы вашего tty).

Мюррей Дженсен
источник
Действительно, очень опытный знает об этом, когда требуется преобразование из CRLF в качестве альтернативы отсеву и использованию dos2unix или подобного. Использование Ctrl-V - урок на один день.
Маккензм
5

vimиспользовать \nдля представления нулевого символа \0в памяти, чтобы vimфайл дескриптора содержал нулевой символ (пока viне может).

Использование \nтолько совпадения конца строки в буфере, а не перевода строки в строке при использовании в выражении.

Смотрите : h NL-used-for-Null и : h CR-used-for-NL для получения более подробной информации.

cuonglm
источник
1

Протестировано с Neovim ( nvim) и Vimверсиями

NVIM v0.3.0
VIM - Vi IMproved 8.1

Удалить новую строку:

cell
allele
rs2981578
fgfr2

Здесь \nсовпадает с символами новой строки ( однако для вставки символа новой строки используйте \r):

:'<,'>s/\n/|/g

cell|allele|rs2981578|fgfr2

Добавить новую строку:

Нет:

cell|allele|rs2981578|fgfr2

:'<,'>s/\n/|/g

cell^@allele^@rs2981578^@fgfr2

^@является диакритическим знаком для LF (перевод строки; см. http://vimhelp.appspot.com/digraph.txt.html#digraphs-default )

Да:

cell|allele|rs2981578|fgfr2

:'<,'>s/|/\r/g

cell
allele
rs2981578
fgfr2

Чтобы ответить на вопрос ОП (как заменить один \nна два \n\n), просто добавьте другой \r:

cell
allele
rs2981578
fgfr2

:'<,'>s/\n/\r\r/g

cell

allele

rs2981578

fgfr2

... т.е. соответствует исходной функции новой строки ( \n) и заменяет ее двумя символами новой строки / возврата каретки ( \r\r).

Виктория Стюарт
источник