Vim - Добавление пустой строки между строками


15

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

например. из

line 1
line 2
line 3

line 4
line 5

в

line 1

line 2

line 3

line 4

line 5

Ответы:


27

Команда 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), - это одна из тех удивительно полезных команд, на которые вы скоро поверите, а потом ужасно пропустите в редакторах. у которого его нет.


1
Точно. Я обычно смотрю на короткие сокращения, как, :%norm oно оказывается, что это не работает, как задумано в случае o. +1
сехе

Введите :%s/$/, затем нажмите ^V, затем нажмите Enter.
jpaugh

1
@jpaugh Предполагая, что вы имеете в виду :%s/$/<C-V><CR><CR>(использовать обычное кодирование клавиш vim-folk), этот подход просто добавляет новую строку после каждой строки. То есть строки, которые уже разделены пробелами (см. Строка 3 -> Строка 4, в тексте примера), получают дополнительные пустые строки. Первоначальный вопрос заключался в том, чтобы избежать добавления лишних пустых строк там, где они уже существуют в начальном тексте.
Тревор Пауэлл

3

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

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

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

Благодарность! Это работает, и это не добавляет больше строк, если я снова запускаю поиск (если, скажем, я добавил новые строки в свой файл).

1
Не могли бы вы объяснить, что означает каждое из регулярных выражений в шаблоне поиска? Глядя на справку vim, \n\@<!\nозначает ли это, что любой разрыв строки, который не сразу после очередного перехода строки, является правильным? Но я не мог понять, что \n\@!значит. Я хотел бы понять это, чтобы я мог изучить и применить его к другим шаблонам поиска :)

Да, \n\@<!\nозначает любой разрыв строки, который не следует сразу за очередным переводом строки. \n\@!соответствует нулевой ширине, если предыдущий атом (т.е. \n) не совпадает непосредственно перед тем, что следует. Попробуй :help \@<!посмотреть документацию по этому в vim. Я
Саймон

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 в командном режиме для перемещения вниз по строке. Затем войдите в режим вставки и добавьте следующую строку. Повторите при необходимости? Надеюсь это поможет!


kдвижется вверх по линии. jдвижется вниз по линии.
Нил Форрестер

Да, действительно так и есть. Моя ошибка. Спасибо, Нил!

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

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

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

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

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

В моем файле много строк. Есть ли способ сделать поиск по регулярному выражению и вставить пустую строку для всего файла? Я смотрел на stackoverflow.com/questions/2673209/… но не мог понять, что означают все команды регулярных выражений.

Посмотрите мое редактирование выше для альтернативного способа сделать то же самое в одной команде, и без рекурсивного отображения. Первый способ должен работать для всего файла, хотя.
Нил Форрестер

0

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

:%!sed G|cat -s

Вместо того, чтобы пытаться «вимгольфить» короткую команду, небольшое объяснение довольно непонятных опций будет более полезным.
Инго Каркат

0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.