Eu gostaria de unir linhas apenas para linhas que possuem certo padrão (como ;
), no entanto, quando o uso g/;/j
não funciona como esperado, a menos que seja chamado algumas vezes.
Por exemplo, o seguinte conteúdo:
a
1;
2;
3;
4;
5;
b
6;
7;
8;
9;
c
ao usar: :g/;/j
a saída é:
a
1; 2;
3; 4;
5; b
6; 7;
8; 9;
c
ou :g/;/-j
dá:
a 1; 2; 3; 4; 5;
b 6; 7; 8; 9;
c
semelhante com: :g/;\_.\{-};/j
.
Minha saída esperada é:
a
1; 2; 3; 4; 5;
b
6; 7; 8; 9;
c
ou algo semelhante, para que todas as linhas que contenham o padrão sejam unidas.
Como isso pode ser alcançado?
global-command
kenorb
fonte
fonte
:g/;/j
não funciona porque é feito em duas passagens: primeiro o buffer é verificado, depois o comando é aplicado às linhas correspondentes.Respostas:
Possível explicação do problema
Eu acho que a razão pela qual
:g/;/j
não funciona é porque o:g
comando opera com um algoritmo de 2 passagens:;
Durante a segunda passagem,
:g
junta a linha1;
com a linha2;
porque1;
foi marcada durante a primeira passagem. No entanto eu suspeito que (não tenho certeza) que não se juntar1; 2;
com3;
porque a linha2;
não existe mais, o seu conteúdo tem sido fundida com a linha1;
que já foi processado.Então,
:g
procura a próxima linha que foi marcada durante a primeira passagem (3;
) e a une à seguinte (4;
). Depois que se repete problema, ele não pode se juntar3; 4;
com5;
porque a linha4;
não existe mais.Solução 1 (com vimscript)
Talvez você possa chamar uma função sempre que uma linha contendo
;
for encontrada para verificar se a linha anterior também contém um ponto e vírgula:Em seguida, use o seguinte comando global:
Ou sem uma função:
Solução 2 (sem vimscript)
Sempre que o comando global
:g
encontra o padrão,;
ele executa o comando:.,/^[^;]*$/-1j
Pode ser dividido assim:
Onde :
b
pode ser dividido ainda mais assim:j
é a forma abreviada do comando Ex:join
que, como a maioria dos outros comandos Ex, pode ser precedido por um intervalo.Aqui, é precedido pelo intervalo:
.,/^[^;]*$/-1
(a,b
)Um intervalo segue a forma
a,b
ondea
eb
geralmente são 2 números de linha e permite operar em um grupo de linhas cujo número está entrea
eb
, em vez de apenas um.Portanto, o
j
comando une todas as linhas entre a atual (a
) e a próxima que não contém ponto e vírgula menos uma (b
).Para mais informações, veja:
fonte
Faço associações semelhantes o tempo todo com uma pesquisa global e substituo:
\n
corresponde à nova linha.Para localizar e excluir linhas em branco:
Não sei por que, mas se você quiser inserir uma nova linha, precisará usar
\r
fonte
s
só irá funcionar apenas para uma linha, para torná-lo global, você precisa usar%s
, mas, em seguida, ele vai juntar-se quase todas as linhas, incluindo os não;
linhas:s
comando exatamente para o que deseja. Eu acho que isso%s/;\n\(.*;\)\@=/;/
faz o que você precisa.