I would like to delete every other line from a Vim buffer, starting with the second one, i.e., lines 2, 4, 6, etc. For example, if the buffer’s contents is:
a
An elegant (and efficient) way to accomplish the task is to invoke
the :+delete
command removing the line following the current one,
on every line using the :global
command:
:g/^/+d
Invoke sed:
:% !sed -e '2~2 d'
^^^^ pipe file through a shell command
^^^^^^ the command is sed, and -e describes an expression as parameter
^^^^^ starting with the second line, delete every second line
you can try this in vim
:1,$-1g/^/+1d
I'll try to be more clear (two parts)
first part the selection range (:from,to
)
second part the action (d
delete)
:1,$-1
)g
) delete (+1d
) next lineyou can try to move to the first line of your file and execute :+1d
you will see the next line disappear
I know it is muddy, but it's vim and it works
We can use :normal
or :norm
to execute given normal mode commands. Source.
:%norm jdd
You can use Vim's own search and substitute capabilities like so: Put your cursor at the first line, and type in normal mode:
:.,/fff/s/\n.*\(\n.*\)/\1/g
.,/fff/
is the range for the substitution. It means "from this line to the line that matches the regex fff
(in this case, the last line).s///
is the substitute command. It looks for a regex and replaces every occurrence of it with a string. The g
at the end means to repeat the substitution as long as the regex keeps being found.\n.*\(\n.*\)
matches a newline, then a whole line (.*
matches any number of characters except for a newline), then another newline and another line. The parentheses \(
and \)
cause the expression inside them to be recorded, so we can use it later using \1
.\1
inserts the grouped newline and the line after it back, because we don't want the next line gone too - we just want the substitution mechanism to pass by it so we don't delete it in the next replacement.This way you can control the range in which you want the deletion to take place, and you don't have to use any external tool.
You can always pipe though a shell command, which means you can use any scripting language you like:
:%!perl -nle 'print if $. % 2'
(or use "unless" instead of "if", depending on which lines you want)