Как делает: $ g/^/,/./-j (уменьшают несколько пустых строк до единственного пробела), работа в энергии?

В статье, Регулярных выражениях Vim, Oleg Raisky дает следующую команду для сокращения нескольких пустых строк до единственного пробела:

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

Кто-то может описать, как это работает?

Я знаю :g команда и регулярные выражения. Но я не понял что часть /,/./-j делает.

27
задан Mert Nuhoglu 13 June 2010 в 11:18
поделиться

1 ответ

Это действительно гениально. Давайте разберемся с этим. Команда ex

g/^$/xyzzy

будет искать все пустые строки и выполнять команду xyzzy (произвольная команда ex ) для каждой из них.

Сложность здесь в том, что команда xyzzy в вашем случае является еще одной командой замены :

,/./-j

, /. / - задает диапазон. Он имеет форму <начало>, <конец> и, поскольку перед запятой ничего нет, предполагается, что текущая строка (та, где вы нашли пустую строку) является началом.

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

Другими словами, конец диапазона - это последняя пустая строка после или рядом с той, с которой вы сейчас работаете.

Затем вы выполняете соединение в этом диапазоне.

Если начало и конец диапазона были равны (в разделе была только одна пустая строка), объединение ничего не делает. Если они не равны, join объединит их всех.

Это способ объединения нескольких пустых строк в одну.

Давайте посмотрим на пример (номеров строк нет в файле):

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 указан двухпроходный алгоритм: один для маркировки строк, другой для выполнения операции.

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

51
ответ дан 28 November 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: