Antes de tudo, sendo este o meu primeiro post aqui, gostaria de dizer que achei o VIM uma ótima ferramenta e o fórum aqui muito útil para encontrar respostas para perguntas, com muitas pessoas prestando inestimável assistência. Ainda sou muito novo no VIM, então praticamente tudo que aprendi sobre isso veio daqui.
Minha pergunta é: eu sei como reverter TODAS as linhas em um arquivo (: g / ^ / m0 entre outras maneiras), mas existe uma maneira de reverter a cada 4 linhas em um arquivo, para que
line1
line2
line3
line4
line5
line6
line7
line8
...
torna-se
line4
line3
line2
line1
line8
line7
line6
line5
...
Você pode assumir que sempre haverá um múltiplo exato de 4 linhas nesses arquivos.
Respostas:
O comando
:Reverse
explicado no Vim Wiki pode ser usado para isso (você pode incluí-lo no seu.vimrc
para torná-lo permanente):Em seguida, você pode gravar uma macro para executar o comando a cada quatro linhas:
Explicação:
qm
: 'q' no modo normal inicia (e para) a gravação de uma macro em um determinado registro (registrador 'm', neste caso, mas pode ser qualquer outra letra)V
: entre no modo visual e selecione a linha atual3j
: expanda a seleção visual para as próximas 3 linhas:Reverse<cr>
: execute o comando Reverse nas linhas selecionadas (<cr>
aqui está a entertecla)4j
: vá para as próximas linhas inalteradasq
: para de gravar a macro1000@m
: execute a macro gravada no registro 'm' 1000 vezes (você pode aumentar esse número se o arquivo tiver mais de 4000 linhas)Editar:
Conforme mencionado nos comentários, você pode usar uma macro recursiva em vez de usar uma contagem:
qM
: se o registro especificadoq
estiver em maiúsculas, a macro será anexada ao registro (o que também é útil quando você percebe quando perdeu as últimas etapas em uma macro complexa)@m
: executar a macro no registrom
q
: pare de anexar a macroApesar de criado como uma macro, você pode criar um comando para isso, se for uma tarefa comum no seu fluxo de trabalho:
function! Reverse4()
/endfunction
: define uma nova funçãolet reg_m = @m
: salva o conteúdo atual do registrom
let @m = "<c-r><c-r>m"
: insira a macro no registrom
- observe que<c-r>
é a notação vim para Ctrl+ re que você deve digitar isso, não copiar / colar, para que sua linha seja semelhantelet @m = 'V3j:Reverse^M4j@m'
e conterá um caractere especial (^ M)normal! @m
: o comando normal executa seu argumento conforme foi digitado no modo normal, portanto, executa a macro recursivalet @m = reg_m
: restaura o conteúdo do registrom
, para que você não precise se lembrar de que esse registro está sendo usado nessa função e evite usá-locommand! Reverse4 call Reverse4()
: crie um novo comando para esta funçãoDependendo das suas necessidades, você pode aprimorá-lo, por exemplo: passe um argumento para o comando e a função para que funcione para qualquer número de linhas, em vez de ser corrigido em grupos de 4 linhas.
fonte
1000@q
corte, você também pode usar uma macro recursiva:qmqqm ... @mq@m
.command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl
em algum lugar do seu vimrc.Como em todas as ações repetitivas , se você puder fazer algo uma vez com operações básicas de edição, poderá fazê-lo facilmente várias vezes gravando uma macro.
(Neste caso, usarei uma macro recursiva, mas você pode gravar uma macro não recursiva e reproduzi-la várias vezes martelando
@@
ou usando uma contagem.)Quebrado
gg
: Move para o início do arquivo.qqq
: Limpe o registroq
. Veremos por que isso é necessário na etapa 5.qq
: Comece a gravar uma macro para registrar qddjjpkddkkPjddpjj
: Uma série de operações que reordena as quatro primeiras linhas simplesmente excluindo e colando-as manualmente. (Isso pode parecer complicado à primeira vista, mas não se deixe enganar Isso é coisa muito básico que você aprendeu nos primeiros 5 minutos ou mais de.vimtutor
:j
,k
,dd
,p
,P
)@q
: Ligue para a macro! Nesse ponto, o registroq
não contém nada (porque o limpamos na etapa 2), portanto nada acontecerá.q
: Pare de gravar a macro.@q
: Repita a macro recursiva quantas vezes for necessário.Nota: O acima não produzirá os resultados desejados se o arquivo contiver um número de linhas que não sejam exatamente divisíveis por quatro. Para interromper a macro mais cedo, se não houver mais quatro linhas, precisamos executar um comando no modo normal do Vim que falhará, antes de começarmos a aplicar as edições na etapa 4. Podemos fazer isso tentando mover para baixo uma linha três vezes (e depois faça backup) antes de começarmos a mover as linhas:
jjj3k
Portanto:
fonte
q
, ela deve estar vazia, caso contrário, estragará suas edições.qqqggqqjjjkddkkPjddjpkddkkPjjjj@qq@q
where I can just use the one-line custom command each time I need to do this
- observe que você não precisa recriar a macro toda vez que precisar usá-la, pois é possível armazená-la como uma função / comando no seu vimrc.Você também pode fazer isso com um
Ex
comando usandosed
como filtro externo:Esta versão ignorará (excluir) quaisquer linhas extras além de um múltiplo de 4. Para manter o último conjunto de menos de 4 linhas (invertido), use:
o
%
aqui significa "Toda linha no buffer".O
!
comando significa "Execute o seguinte comando com as linhas especificadas como entrada e substitua as linhas especificadas pela saída do comando". (É chamado de filtro; muito útil para coisas como classificação, por exemplo,:%!sort
classificará todas as linhas do seu arquivo;:2,8!sort
classificará as linhas 2 a 8, etc.)sed
é a ferramenta de edição de fluxo e é encontrada em todos os sistemas semelhantes ao Unix. Os principais conceitossed
usados aqui são o "espaço do padrão" (que por padrão contém apenas cada linha da entrada) e o "espaço de espera" (onde é possível colar texto extra ao usarsed
para salvá-lo enquanto processa outras linhas de entrada).-n
é uma opção dosed
comando para suprimir suas ações padrão de impressão do espaço do padrão (porque, neste caso, só queremos imprimir quando o explicitarmos).$p
nosed
comando significa "Se você estiver na última linha desed
entrada da impressora, imprima (o espaço do padrão)."h
significa "colar o conteúdo atual do 'espaço padrão' no 'espaço de espera', substituindo o que estiver lá".n
significa "substituir o conteúdo do 'espaço padrão' pela próxima linha da entrada".G
significa "anexado ao 'espaço padrão': uma nova linha seguida pelo conteúdo do 'espaço reservado'."Tomados em conjunto, o
sed
comando armazena quatro linhas de saída, revertendo-as à medida que as armazena e depois as imprime. Os$p
comandos adicionados na segunda versão garantem que, se a última linha do arquivo for alcançada, exceto em um múltiplo de 4 linhas, as linhas ainda serão impressas.Para uma abordagem alternativa e interativa, ainda sem o uso de recursos específicos do Vim e também sem o uso de um filtro externo:
para ir para a quarta linha.
para inverter as quatro linhas anteriores (1-4) e deixar o cursor na linha 8.
.m -4
move a linha atual para logo após a linha quatro linhas para trás (deixando o cursor na linha movida).+3m .
move a linha que está 3 linhas após a linha atual, para logo após a linha atual, deixando o cursor na linha movida.+2m .
claro que funciona da mesma maneira.+5
coloca o cursor cinco linhas abaixo de onde está.Repita conforme desejado.
No Vim, você pode repetir todo esse comando com
@:
e depois repetir com@@
. No POSIXvi
ouex
você precisaria inserir:.m -4 | +3m . | +2m . | +5
como uma linha de texto, exclua-o em um buffer nomeado (registrador) e execute esse buffer nomeado (registrador).Portanto, no
ex
modo, revertendo linhas interativamente usando apenas os recursos especificados no POSIX e começando com 17 linhas de texto:Leitura adicional:
ex
vi
fonte
4G:.m -4 | +3m . | +2m . | +5<Enter>@:
em seguida,@@
repetido até que o arquivo é totalmente processada. Eu recomendo instalar o MobaXterm, no entanto. :)Inglês simples: para cada linha, mova a linha atual para cima
lnum % 4
, a menos quelnum % 4 == 0
, nesse caso, mova a linha atual para cima4
.Além disso, para reverter todas as
n
linhas, substitua as4
no comando acima porn
.fonte