Як: g /^$/,/./- j (зменшити кілька порожніх рядків до одного порожнього) працює у vim?


21

У статті « Vim Regular вирази» Олег Райський дає таку команду для зменшення кількох порожніх рядків до одного порожнього:

:g/^$/,/./-j

Хтось може, будь ласка, описати, як це працює?

Я знаю :gкомандні та регулярні вирази. Але я не зрозумів, що /,/./-jробить.

Відповіді:


24

Це дійсно досить геніально. Давайте розбимо його. exкоманда

g/^$/xyzzy

буде шукати всі порожні рядки та виконувати xyzzyкоманду (довільну exкоманду) на кожному з них. Зауважте, що xyzzyце не реальна ex команда, вона є лише як заповнювач, як зазначено в наступному абзаці.

Тут складно, що xyzzy"команда" у вашому випадку - це ще одна команда пошуку:

,/./-j

,/./-Визначає діапазон. Це має форму, <start>,<end>і оскільки перед комою немає нічого, він передбачає, що поточний рядок (той, де ви знайшли порожній рядок) - це початок.

Після кома - /./-це означає пошук наступного символу ( .означає будь-який символ), а потім створити резервну копію одного рядка ( /./-скорочено, /./-1оскільки ця мається на увазі, якщо значення не задано). Ви знайдете цей візерунок .у першому непорожньому рядку, що слідує за тими, якими ви працюєте.

Іншими словами, кінець діапазону - це останній порожній рядок після або в тому, на якому ви зараз працюєте.

Потім ви виконуєте з'єднання за цим діапазоном.

Якщо початок і кінець діапазону були рівними (у розділі був лише один порожній рядок), приєднання нічого не робить. Якщо вони не рівні, приєднайтесь до них усіх.

Ось так воно поєднує кілька порожніх рядків в одне.

Розглянемо приклад (номери рядків призначені лише для пояснення, їх немає у фактичному файлі):

1 Line 1
2
3 Line 3
4 Line 4
5
6
7
8
9 Line 9

g/^$/Команда знайде все порожні рядки і виконувати операції над ними (це лінія 2, 5, 6, 7 і 8).

Для рядка 2 ,/./-jбуде встановлено діапазон від 2 до 2 (наступний .знаходимо на рядку 3, потім віднімаємо 1, щоб отримати 2). Об'єднання в діапазоні 2,2 нічого не робить.

Для рядка 5 ,/./-jбуде встановлено діапазон від 5 до 8 (наступний .знайдений у рядку 9, потім віднімаємо 1). Об'єднання в діапазоні 5,8 приєднає всі ці лінії разом.

Операція не виконується на лініях, які зникають як частина попередньої операції. Це тому, що не було б сенсу обробляти рядки, які були видалені на початку циклу.

Іншими словами, оскільки рядки з 6 по 8 видаляються (поєднуються з рядком 5), глобальна команда не працює над ними.

Це ґрунтується на тому, що в vimдокументації вказано алгоритм з двома проходами, один для позначення ліній, один для виконання операції.


2
Зауважте, що ця команда поскаржиться, якщо в кінці файлу є порожні рядки.
Wildcard
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.