Como posso reverter a ordem das linhas para que a primeira linha apareça no final e a última linha apareça primeiro? (Podem ser todas as linhas em um buffer, um intervalo de endereços ou uma seleção de modo visual em linhas.)
Eu gostaria de transformar
rat
ox
tiger
⋮
dog
pig
para dentro
pig
dog
⋮
tiger
ox
rat
sem recorrer a um comando externo como tac
.
rearrangement
200_success
fonte
fonte
Respostas:
O poder do global funcionará aqui:
Ou, mais simplesmente (obrigado @tommcdo)
A primeira corresponderá a todas as linhas e, para cada linha, exclua-a e cole-a na parte superior do arquivo. À medida que se move pelo arquivo, ele reverte o texto.
O segundo corresponde de maneira semelhante a todas as linhas e a move para a parte superior do arquivo.
Nota: Ambos funcionam em todo o arquivo e não se aplicarão corretamente à reversão de um subconjunto das linhas. Veja a resposta de Ingo Karkat para uma solução que funciona dentro de um intervalo.
Descrição:
g
comando global/^/
corresponde a qualquer linha que tenha um início (ou seja, todas as linhas)exe
execute a seguinte sequência de caracteres"normal
executar comandos no modo normaldd
excluir linhagg
mover para o topo daP
pasta do arquivo acima da posição atualmove 0
move a linha atual para abaixo da linha 0 (que a coloca na posição 1 ou na primeira linha do arquivo)fonte
:normal
comando, podemos usar o comando Ex:move 0
, que move a linha para o início do buffer.:execute
é necessário apenas quando o comando precisa ser construído dinamicamente, por exemplo:execute 'normal' g:user_command
.:execute
porque, muitas vezes, acabo anexando outros comandos Ex após o existente mais tarde, e é mais conveniente que eu:exe
já tenha o que existe do que precisar voltar e inseri-lo mais tarde. Infelizmente, esse hábito vazou para esta resposta, onde não se aplica tanto.:execute
: como uma string é usada , fornece uma definição clara de onde os comandos do modo normal terminam, mesmo que eu não esteja construindo a string, é mais fácil encontrar aspas equilibradas do que procurar<esc>
ou o que quer que seja para encerrar o modo. Novamente, isso é preferência e hábito pessoais. :-):9,11g/^/move 8
... O último número precisa ser o início do intervalo menos 1 (adaptado da resposta do Ingo).Essa linha única (para o seu
~/.vimrc
) define um:Reverse
comando; você também pode usar a:global
peça diretamente, mas a sintaxe da:move
(que iterativamente muda as linhas para antes do início do intervalo, revertendo-a) não é fácil de memorizar:fonte
<line1>
&<line2>
são obrigados a fazer isso funcionar em um intervalo, ou seja::7,9Reverse
(são características decommand
, nãoglobal
oumove
). Quanto mais simples:command! -bar -range=% Reverse :global/^/m 0
também irá funcionar, mas apenas para todo o buffer ...Pure Vim:
Explicação:
Fonte: Inverta todas as linhas e Potência de g na vim wikia.
Poucos exemplos usando comandos externos:
tac
(parte dos GNU coreutils -cat
invertida):tail
no BSD / OSX (não compatível com POSIX):Para mais ideias, consulte:
fonte
:g/^/m0
o mesmo que:g/^/move 0
, qual é a resposta de João?tac
também). Mas eu suspeito que o voto negativo foi por causa da resposta ser repetida.tac
foi mencionado pelo OP, mas todas as outras perguntas semelhantes seriam duplicadas disso, então é bom mencioná-lo novamente. John tirou esse cmd do comentário do @tommcdo, eu o peguei inicialmente do DerMike , mas acho que ele tirou da wikia, então dei créditos ao vim wikia, para que não seja completamente duplicado, pois a explicação é completamente diferente.No espírito do VimL funcional:
getline(1, line('$'))
retorna uma lista de todas as linhas no buffer.'$'
é um argumento especial para oline()
qual indica a última linha no buffer.reverse(...)
inverte a lista de entrada no local. Seria necessário usarreverse(copy(...))
se a lista de entrada não deveria ser modificada.setline(1, ...)
substitui a linha especificada pelo segundo argumento. Quando o segundo argumento é uma lista, o mesmo número de linhas que o comprimento da lista é substituído pelo conteúdo da lista.Se desejar, também é possível definir um comando que possui um intervalo (
%
buffer inteiro padrão )fonte
hlsearch
ativadas), como o:g/
comando das outras respostas ... O desempenho talvez seja pior, embora? Uma vez quegetline(1, line('$'))
recebe todo o buffer na memória.reverse()
parece ser no local, de modo que deve ter muito pouca memória como tal ...De acordo com a documentação do Vim usr_12.txt - Truques inteligentes
fonte
Usando números relativos. O parágrafo começa na linha 13 e gera mais 4 linhas
fonte