Это действительно довольно гениально.Давайте разберемся с этим.Команда 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 указан двухпроходный алгоритм: один для разметки строк, другой для выполнения операции.
I может быть ошибочным в этомточка (это будет не в первый раз), но это деталь реализации, которая не влияет на функциональность.