Como: g /^$/,/./- j (reduz várias linhas em branco para um único espaço em branco) funciona no vim?

21

No artigo Expressões regulares do Vim , Oleg Raisky fornece o seguinte comando para reduzir várias linhas em branco para um único espaço em branco:

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

Alguém pode descrever como isso funciona?

Eu sei :gcomando e expressões regulares. Mas eu não entendi o que a parte /,/./-jfaz.

200_success
fonte

Respostas:

24

Realmente é bastante engenhoso. Vamos dividir. O excomando

g/^$/xyzzy

procurará todas as linhas vazias e executará o xyzzycomando (um excomando arbitrário ) em cada uma delas. Observe que xyzzynão é um comando real ex , apenas existe como um espaço reservado, conforme o próximo parágrafo.

A parte complicada aqui é que o xyzzy"comando" no seu caso é outro comando de pesquisa:

,/./-j

O ,/./-especifica um intervalo. Esse é o formato <start>,<end>e, como não há nada antes da vírgula, ele assume que a linha atual (aquela em que você encontrou a linha em branco) é o início.

Após a vírgula, o /./-que significa procurar o próximo caractere ( .significa qualquer caractere) e fazer o backup de uma linha ( /./-é abreviada, /./-1já que a letra está implícita se nenhum valor for fornecido). Você encontrará esse padrão .na primeira linha que não estiver em branco após a que você está operando.

Em outras palavras, o final do intervalo é a última linha em branco após ou na qual você está operando atualmente.

Então você executa uma junção nesse intervalo.

Se o início e o final do intervalo forem iguais (apenas uma linha em branco estava na seção), a junção não fará nada. Se eles não forem iguais, a junção juntará todos eles.

É dessa maneira que combina várias linhas em branco em uma.

Vamos ver um exemplo (os números das linhas são apenas explicativos, não estão no arquivo real):

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

O g/^$/comando encontrará todas as linhas vazias e executará sua operação nelas (estas são as linhas 2, 5, 6, 7 e 8).

Para a linha 2, ,/./-jconfigurará um intervalo de 2 a 2 (o próximo .é encontrado na linha 3 e subtrai 1 para obter 2). Uma junção no intervalo 2,2 não faz nada.

Para a linha 5, ,/./-jconfigurará um intervalo de 5 a 8 (a seguir será .encontrado na linha 9 e subtrairá 1). Uma junção no intervalo 5,8 unirá todas essas linhas.

A operação não é executada em linhas que desaparecem como parte de uma operação anterior. Isso porque não faria sentido processar linhas que foram excluídas no início do ciclo.

Em outras palavras, como as linhas 6 a 8 são excluídas (combinadas com a linha 5), ​​o comando global não opera sobre elas depois disso.

Isso se baseia no fato de a vimdocumentação indicar um algoritmo de duas passagens, um para marcar as linhas, outro para executar a operação.


fonte
2
Observe que este comando irá reclamar se você tiver alguma linha vazia no final do seu arquivo.
Curinga