Ответы:
Команда Vim's: g предназначена именно для такого рода задач; запускать одно действие в каждой строке, которое соответствует определенному шаблону. Вот мой ответ:
:g/.\n\n\@!/norm o
Шаблон, который я использую, есть /.\n\n\@!/
. Разбивая это на составляющие части:
.
Соответствует любому символу в строке. (используется для немедленного удаления любых существующих пустых строк из рассмотрения)\n
Соответствует одному \ n в конце символа выше\n\@!
Сбой совпадения, если есть другой \ n сразу после более раннего \ n.(Проверьте :h E59
для получения дополнительной информации \@!
и аналогичных спецификаторов соответствия в регулярных выражениях - есть еще пара других!)
Таким образом, регулярное выражение команды: g теперь выбрало каждую непустую строку, которая заканчивается одной новой строкой и за которой не следует пустой строки.
После шаблона в :g
операторе появляется команда для запуска по соответствующим строкам. В этом случае я сказал ему выполнить команду в обычном режиме (сокращенно до norm
), а команда для запуска - просто o
, которая вставляет пустую строку ниже текущей строки.
Таким образом, команда находит каждую строку, в которой нет пустой строки, и добавляет ее. И это все, что нужно сделать! Возможно, вы захотите проверить статью vim wiki о Power of G, чтобы узнать о более причудливых вещах, которые вы можете сделать :g
(и это отрицательная сестра :v
), - это одна из тех удивительно полезных команд, на которые вы скоро поверите, а потом ужасно пропустите в редакторах. у которого его нет.
:%s/$/
, затем нажмите ^V
, затем нажмите Enter
.
:%s/$/<C-V><CR><CR>
(использовать обычное кодирование клавиш vim-folk), этот подход просто добавляет новую строку после каждой строки. То есть строки, которые уже разделены пробелами (см. Строка 3 -> Строка 4, в тексте примера), получают дополнительные пустые строки. Первоначальный вопрос заключался в том, чтобы избежать добавления лишних пустых строк там, где они уже существуют в начальном тексте.
Когда я протестировал глобальный ответ @ NeilForester на поиск и замену, я обнаружил, что он пропускает каждую намеченную замену в последовательных непустых строках, если в строках содержится только один символ в каждой. Похоже, это связано с тем, что шаблон начинает совпадать в каждом случае после последнего символа, которому он соответствует в предыдущем случае.
Использование lookbehind и lookahead решает эту проблему и также делает регулярное выражение немного короче:
:%s/\n\@<!\n\n\@!/\r\r/g
\n\@<!\n
означает ли это, что любой разрыв строки, который не сразу после очередного перехода строки, является правильным? Но я не мог понять, что \n\@!
значит. Я хотел бы понять это, чтобы я мог изучить и применить его к другим шаблонам поиска :)
\n\@<!\n
означает любой разрыв строки, который не следует сразу за очередным переводом строки. \n\@!
соответствует нулевой ширине, если предыдущий атом (т.е. \n
) не совпадает непосредственно перед тем, что следует. Попробуй :help \@<!
посмотреть документацию по этому в vim. Я
Другой путь:
%s/\(.\)\n\(.\)/\1\r\r\2/
Что значит,
\(.\) match and capture a non-newline character,
\n match a newline
\(.\) match and capture a non-newline character
заменить на: первый захват, двойной перевод строки и второй захват.
Например, line1\nLine2
результаты в \1 = 1
и \2 = L
.
Поправь меня, если я ошибаюсь. Я полагаю, что вы используете букву k в командном режиме для перемещения вниз по строке. Затем войдите в режим вставки и добавьте следующую строку. Повторите при необходимости? Надеюсь это поможет!
k
движется вверх по линии. j
движется вниз по линии.
/[^\n]\n[^\n]
:map <F2> no<esc><F2>
Затем нажмите <F2>
. Это будет искать две последовательные непустые строки, а затем добавить строку между ними, несколько раз.
Редактировать:
Вот альтернативный способ сделать это с помощью одного глобального поиска и замены:
:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g
Попробуйте эту команду ( 16
символы):
:%!sed G|cat -s
:%norm o
но оказывается, что это не работает, как задумано в случаеo
. +1