Відповіді:
Команда Vim: g призначена саме для такого роду завдань; виконання однієї дії у кожному рядку, який відповідає певному шаблону. Ось моя відповідь:
:g/.\n\n\@!/norm o
Я використовую схему /.\n\n\@!/
. Розбивши це на складові частини:
.
Відповідає будь-якому символу в рядку. (використовується для негайного вилучення будь-яких існуючих порожніх рядків з розгляду)\n
Відповідає одному \ n в кінці символу вище\n\@!
Не вдалося збігнути, якщо є інше \ n одразу після попереднього \ n.(Перевірте, чи :h E59
більше інформації про \@!
та подібні специфікатори відповідності в регулярних виразах - є ще пара!)
Отже, регулярний вираз команд: g тепер вибрав кожен непустий рядок, який закінчується одним новим рядком, і за яким не слідує порожній рядок.
Після шаблону в :g
операторі з'являється команда для запуску на відповідні рядки. У цьому випадку я сказав йому виконати команду в звичайному режимі (скорочено norm
), а команда для запуску - це просто o
, яка вставляє порожній рядок нижче поточного рядка.
Таким чином, команда знаходить кожен рядок, який не має порожнього рядка під ним, і додає його. І це все є! Можливо, ви хочете перевірити статтю Power of G від vim wiki для більш вигадливих речей, які ви можете зробити :g
(і це негативна сестра, :v
) - це одна з тих дивовижно корисних команд, на які незабаром ви зробите покладатися, а потім страшно пропускаєте редакторів. які не мають.
:%s/$/
, потім натисніть ^V
, потім натисніть Enter
.
:%s/$/<C-V><CR><CR>
(використовувати загальне vim-folk кодування клавіш), такий підхід просто додає новий рядок після кожного рядка. Тобто рядки, які вже розділені пробілами (див. Рядок 3 -> рядок 4, у тексті прикладу), завершуються, отримуючи зайві порожні рядки. Оригінальним питанням було уникати додавання зайвих порожніх рядків там, де вони вже існували у вихідному тексті.
Коли я перевірив глобальну відповідь на пошук та заміну @ NeilForester, я виявив, що він пропускав кожну другу передбачувану заміну в послідовних непорожніх рядках, якщо рядки мали лише один символ у кожному. Це, мабуть, пояснюється тим, що візерунок починає співпадати в кожному випадку після останнього символу, який відповідає попередньому випадку.
Використання перспективи та пошуку даних вирішує цю проблему і також робить регекс трохи коротшим:
:%s/\n\@<!\n\n\@!/\r\r/g
\n\@<!\n
означає, що будь-який рядок рядків, який не є одразу після іншого, є правильним? Але я не могла зрозуміти, що \n\@!
означає. Я хотів би зрозуміти це, щоб я міг навчитися та застосувати його до інших моделей пошуку :)
\n\@<!\n
означає будь-яку лінію, яка не одразу слідує за іншою лінією. \n\@!
збігається з нульовою шириною, якщо попередній атом (тобто \n
) не збігається безпосередньо перед наступним. Спробуйте :help \@<!
переглянути документацію про це in 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