Respostas:
O comando g do Vim foi projetado para exatamente esse tipo de tarefa; executando uma única ação em cada linha que corresponda a um padrão específico. Aqui está a minha resposta:
:g/.\n\n\@!/norm o
O padrão que eu uso é /.\n\n\@!/
. Dividindo isso em seus componentes:
.
Corresponde a qualquer caractere na linha. (usado para descartar imediatamente qualquer linha vazia existente da consideração)\n
Corresponde a um \ n no final do caractere acima\n\@!
Falha na partida se houver outro \ n imediatamente após o anterior \ n.(Verifique :h E59
para obter mais informações \@!
e especificadores de correspondência semelhantes em expressões regulares - também existem outros!)
Portanto, a regex do comando: g agora selecionou todas as linhas não vazias que são finalizadas por uma única nova linha e que não são seguidas por uma linha vazia.
Após o padrão em uma :g
instrução, vem o comando para executar nas linhas correspondentes. Nesse caso, eu disse para executar um comando no modo normal (abreviado para norm
), e o comando a ser executado é simplesmente o
, que insere uma linha vazia abaixo da linha atual.
Então, juntos, o comando encontra todas as linhas que não possuem uma linha vazia abaixo e adiciona uma. E é só isso! Você pode verificar o artigo Power of G do wiki do vim para obter coisas mais sofisticadas com as quais você pode fazer :g
(e é irmã negativa :v
) - é um daqueles comandos incrivelmente úteis nos quais você logo confia e depois sente muita falta de editores que não tem.
:%s/$/
, pressione e ^V
, em seguida, pressione Enter
.
:%s/$/<C-V><CR><CR>
(usar a codificação vim-folk comum de pressionamentos de tecla), essa abordagem apenas adiciona uma nova linha após cada linha. Ou seja, linhas que já estão separadas por espaços em branco (consulte Linha 3 -> Linha 4, no texto de exemplo) acabam recebendo linhas em branco extras. A pergunta original era evitar adicionar linhas em branco extras onde elas já existiam no texto inicial.
Quando testei a pesquisa global e a resposta de substituição do @ NeilForester, descobri que ela perdia a cada segundo a substituição pretendida em linhas consecutivas que não estavam em branco se as linhas tivessem apenas um caractere em cada. Parece que o padrão começa a corresponder em cada ocasião após o último caractere correspondente à ocasião anterior.
Usar lookbehind e lookahead resolve esse problema e torna o regex um pouco mais curto também:
:%s/\n\@<!\n\n\@!/\r\r/g
\n\@<!\n
significa que qualquer quebra de linha que não está logo após outra quebra de linha está correto? Mas eu não conseguia entender o que \n\@!
significa. Eu gostaria de entender isso para que eu possa aprender e aplicá-la a outros padrões de pesquisa :)
\n\@<!\n
significa qualquer quebra de linha que não segue imediatamente outra quebra de linha. \n\@!
corresponde à largura zero se o átomo anterior (ie \n
) não corresponder logo antes do que segue. Tente :help \@<!
ver a documentação sobre isso no vim. I
Outra maneira:
%s/\(.\)\n\(.\)/\1\r\r\2/
Que significa,
\(.\) match and capture a non-newline character,
\n match a newline
\(.\) match and capture a non-newline character
substitua por: primeira captura, novas linhas duplas e a segunda captura.
Por exemplo, line1\nLine2
resulta em \1 = 1
e \2 = L
.
Corrija-me se eu estiver errada. Acredito que você use a letra k no modo de comando para mover uma linha para baixo. Em seguida, entre no modo de inserção e adicione a próxima linha. Repita conforme necessário? Espero que isto ajude!
k
sobe uma linha. j
desce uma linha.
/[^\n]\n[^\n]
:map <F2> no<esc><F2>
Então pressione <F2>
. Isso pesquisará duas linhas consecutivas que não estiverem em branco e, em seguida, adicionará uma linha entre elas, repetidamente.
Editar:
Aqui está uma maneira alternativa de fazer isso com uma única pesquisa global e substituir:
:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g
Tente este comando ( 16
caracteres):
:%!sed G|cat -s
:%norm o
mas acontece que isso não funciona como planejado no caso deo
. +1