Ответ 1
Это действительно изобретательно. Пусть сломается. Команда ex
g/^$/xyzzy
будет искать все пустые строки и выполнить команду 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 ничего не делает.
В строке 5 ,/./-j
будет задан диапазон от 5 до 8 (следующий .
, найденный в строке 9, затем вычтите 1). Соединение в диапазоне 5,8 соединяется со всеми этими линиями вместе.
Я не совсем уверен в этом, но я думаю, что операция не может выполняться в строках, которые исчезают как часть более ранней операции. Это потому, что было бы бессмысленно обрабатывать строки, которые были удалены ранее в цикле.
Другими словами, поскольку строки с 6 по 8 удаляются (в сочетании с строкой 5), глобальная команда не работает после них. Я основываю это не что иное, как тот факт, что документация vim содержит двухпроходный алгоритм, один для отметки строк, один для выполнения операции.
Возможно, я ошибаюсь в этой точке (это будет не первый раз), но это деталь реализации, которая не влияет на функциональность.