Como fazer no Vim:
ANTES:
aaa
bbb
ccc
ddd
eee
fff
DEPOIS DE:
aaa
ccc
eee
Como fazer no Vim:
ANTES:
aaa
bbb
ccc
ddd
eee
fff
DEPOIS DE:
aaa
ccc
eee
Respostas:
Você pode usar uma macro para isso. Faça o seguinte.
gg
.qq
.dd
depois.q
.10000@q
PS: Para ir para o modo de comando, pressione Escape algumas vezes.
:g/^/+d
do usuário stackoverflow.com/users/254635/ib (abaixo) é uma maneira mais elegante de resolver isso.
Uma forma elegante (e eficiente) de realizar a tarefa é invocar o :+delete
comando removendo a linha seguinte à atual, em cada linha usando o :global
comando:
:g/^/+d
:1d|g/^/+d
exclui as linhas ímpares.
Podemos usar :normal
ou :norm
para executar determinados comandos de modo normal. Fonte.
:%norm jdd
%norm ddj
saber por que não funciona se você deseja excluir linhas estranhas.
:map ^o ddj^o
^o
Aqui ^ significa CTRL. Macro recursiva para excluir uma linha a cada duas linhas. Escolha bem sua primeira linha e pronto.
:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile
(Para ser digitado em uma linha na linha de comando do vim, excluirá a linha 1,3,5,7, ...)
!perl -ne 'print unless $. % 2'
:-)
if (expression)
qual também funciona para cada terceira linha etc.
Você sempre pode canalizar um comando shell, o que significa que você pode usar qualquer linguagem de script que desejar:
:%!perl -nle 'print if $. % 2'
(ou use "a menos" em vez de "se", dependendo de quais linhas você deseja)
-l
mudar para Perl ... também, eu diria que awk
é um pouco mais difundido do que Perl, embora não seja muito mais hoje em dia, e possa fazer isso mais curto:, :%!awk NR\%2
ou :%!awk 1-NR\%2
para as outras linhas.
:%!awk -- '++c\%2'
alternativamente
:%!awk -- 'c++\%2'
dependendo de qual metade você deseja eliminar.
NR
variável existente ?
:%!awk NR\%2
ou :%!awk 1-NR\%2
, como postei em outro comentário. Isso dificilmente é mais longo.
1-NR
é mais longo que c++
. Sim, eu sei que é um personagem. Como eu disse - a verdadeira razão é que me esqueci disso. Enfim, parece que as pessoas não apreciam a beleza do awk aqui.
NR
é mais curto que ++c
:)
Você pode usar os recursos de pesquisa e substituição do próprio Vim, como: Coloque o cursor na primeira linha e digite no modo normal:
:.,/fff/s/\n.*\(\n.*\)/\1/g
.,/fff/
é o intervalo para a substituição. Significa "desta linha para a linha que corresponde ao regex fff
(neste caso, a última linha).s///
é o comando substituto. Ele procura um regex e substitui todas as ocorrências dele por uma string. O g
no final significa repetir a substituição enquanto a regex continuar sendo encontrada.\n.*\(\n.*\)
corresponde a uma nova linha, depois a uma linha inteira ( .*
corresponde a qualquer número de caracteres, exceto a uma nova linha), a outra nova linha e a outra linha. Os parênteses \(
e \)
fazem com que a expressão dentro deles seja gravada, para que possamos usá-la mais tarde usando \1
.\1
insere a nova linha agrupada e a linha depois dela de volta, porque não queremos que a próxima linha também vá - queremos apenas que o mecanismo de substituição passe por ela, para não excluí-la na próxima substituição.Desta forma, você pode controlar o intervalo em que deseja que a exclusão ocorra e não precisa usar nenhuma ferramenta externa.
$
vez de /fff/
, para o fim do arquivo, independentemente do conteúdo do arquivo.
Como outra abordagem, você também pode usar python se seu vim tiver suporte para ele.
:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]
b = cb[:]
copia temporariamente todas as linhas do buffer atual para b
. b[::2]
obtém cada segunda linha do buffer e as atribui a todo o buffer atual cb[:]
. A cópia para b
é necessária, pois os objetos de buffer não parecem oferecer suporte à sintaxe de fatia estendida.
Este provavelmente não é o "jeito do vim", mas pode ser mais fácil de lembrar se você conhecer o python.
Para excluir linhas ímpares (1,3,5, ..) -> :%s/\(.*\)\n\(.*\)\n/\2\r/g
Para excluir linhas pares (2,4,6, ..) -> :%s/\(.*\)\n.*\n/\1\r/g
Pesquise o texto (forma a primeira linha) seguido por um caractere de nova linha e um pouco mais de texto (forma a segunda linha) seguido por outro caractere de nova linha e substitua o acima pela primeira correspondência (linha ímpar) ou segunda correspondência (linha par) seguido por retorno de carro.
você pode tentar isso no vim
:1,$-1g/^/+1d
Vou tentar ser mais claro (duas partes)
primeira parte do intervalo de seleção ( :from,to
)
segunda parte da ação ( d
deletar)
:1,$-1
)g
) delete ( +1d
) próxima linhavocê pode tentar mover para a primeira linha do seu arquivo e executar :+1d
você verá a próxima linha desaparecer
Eu sei que está lamacento, mas é vim e funciona