15

Как вставить пустую строку между каждыми непустыми строками?

например. от

line 1
line 2
line 3

line 4
line 5

в

line 1

line 2

line 3

line 4

line 5

7 ответов7

26

Команда Vim's:g предназначена именно для такого рода задач; запускать одно действие в каждой строке, которое соответствует определенному шаблону. Вот мой ответ:

:g/.\n\n\@!/norm o

Шаблон, который я использую, - это /.\n\n\@!/ . Разбивая это на составляющие части:

  • . Соответствует любому символу в строке. (используется для немедленного удаления любых существующих пустых строк из рассмотрения)
  • \n Соответствует одному \n в конце символа выше
  • \n\@! Сбой совпадения, если есть другой \n сразу после более раннего \n.

(Проверьте :h E59 для получения дополнительной информации о \@! и аналогичные спецификаторы соответствия в регулярных выражениях - есть еще пара других!)

Таким образом, регулярное выражение команды:g теперь выбрало каждую непустую строку, которая заканчивается одной новой строкой и за которой не следует пустой строки.

После шаблона в операторе a :g следует команда для запуска на совпадающих строках. В этом случае я сказал ему выполнить команду в обычном режиме (сокращенно до norm), а команда для запуска - просто o , которая вставляет пустую строку ниже текущей строки.

Собранные вместе, команда находит каждую строку, в которой нет пустой строки, и добавляет ее. И это все, что нужно сделать! Возможно, вы захотите проверить статью о мощности G в vim wiki, чтобы узнать, что вы можете сделать с ней :g (и это отрицательная сестра :v) - это одна из тех удивительно полезных команд, на которые вы скоро захотите положиться, а затем ужасно скучаю по редакторам, у которых его нет.

3

Когда я тестировал глобальный ответ @ NeilForester на поиск и замену, я обнаружил, что он пропускает каждую намеченную замену в последовательных непустых строках, если в строках содержится только один символ в каждой. Похоже, это связано с тем, что шаблон начинает совпадать в каждом случае после последнего символа, которому он соответствует в предыдущем случае.

Использование lookbehind и lookahead решает эту проблему и также делает регулярное выражение немного короче:

:%s/\n\@<!\n\n\@!/\r\r/g
3

По-другому:

%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

0

Поправь меня, если я ошибаюсь. Я полагаю, что вы используете букву k в командном режиме для перемещения вниз по строке. Затем войдите в режим вставки и добавьте следующую строку. Повторите по мере необходимости? Надеюсь это поможет!

0
/[^\n]\n[^\n]
:map <F2> no<esc><F2>

Затем нажмите <F2> . Это будет искать две последовательные непустые строки, а затем добавить строку между ними, несколько раз.

Редактировать:

Вот альтернативный способ сделать это с помощью одного глобального поиска и замены:

:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g
0

Попробуйте эту команду (16 символов):

:%!sed G|cat -s
0

Я не знаю, как долго ваш файл, но одним из самых простых методов является тип o в командном режиме. И в следующей строке . , Это может быть загружено в простой макрос.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .