Como eu uno a próxima linha quando uma linha corresponde a um regex para todo o documento no VI?

4

Como título, por exemplo, eu tenho linhas como

abcdefg
join!
abcdef
no join
abcdefg
join!

Se uma linha corresponde a regex ^a.+g$ , gostaria que eles fossem unidos, por isso seria:

abcdefgjoin!
abcdef
no join
abcdefgjoin!

Existe uma maneira de fazer isso em VIM ?

    
por Xiaoge Su 30.01.2014 / 20:22

2 respostas

11

No modo normal, J (diferentemente de j , que move o cursor uma linha para baixo) é usado para unir uma linha com a linha logo abaixo dela. No entanto, por padrão, ele adiciona um espaço ao final da primeira linha; para obter o resultado desejado (unindo as linhas sem inserir um espaço adicional), seria necessário usar gJ .

Para usar comandos de modo normal no modo ex (que você insere pressionando : enquanto estiver no modo normal), deve-se usar o comando normal . Veja :h normal dentro do vim. Então, para trabalhar com a próxima linha que combina com o padrão, deve-se usar (note que por padrão, você tem que escapar do + para fazê-lo funcionar com o regex do vim, uma conseqüência de manter compatibilidade com o antigo regex do vi original motor):

:/^a.\+g$/normal gJ

Para trabalhar em todas as linhas que correspondam ao padrão, seria necessário usar o comando :global (consulte :h :g no vim) da seguinte forma:

:global/^a.\+g$/normal gJ

Ou mais concisamente:

:g/^a.\+g$/norm gJ

Também é possível usar o comando ex join (consulte :h :join ) para obter a mesma coisa com um pouco menos de digitação (o ! no final, nesse caso, informa join para não inserir um espaço no final da primeira linha).

:g/^a.\+g$/join!
    
por 30.01.2014 / 22:46
0

Uma solução de regex "pura" seria

:%s/^\(a.\+g\)\n//

A vantagem é que você pode usá-lo para extrair uma string desejável da linha de destino e combiná-la com a seguinte linha; por exemplo, para compensar o espaço em branco

:%s/^(a.\+g\)[ \t]\+\n//
    
por 06.01.2018 / 02:42