How do I delete the last 3 words from every line in Vim by using a single command or by using a recording?
For example, before,
10 3 -5 6 1 0 5
5 9 -1 0 56 8 9
-6 0 45 8 6 3 0
After,
10 3 -5 6
5 9 -1 0
-6 0 45 8
Your safest bet would be:
:%norm $3gElD
Explanation:
For all lines in the file (%
), in normal mode (norm
), move to the end of the line ($
), then 3 WORDs backward (3gE
), one character to the right (l
), and delete the characters under the cursor until the end of the line.
The reason for gE
is to tell VIM to move in terms of what it defines as a WORD: a sequence of non-blank characters, separated with white space (including the dash).
EDIT: In case there's trailing whitespace in a line, the above will fail. You can first get rid of all trailing whitespace in a file with :%s/\s*$//g
You can use this command:
:%norm $3F D
edit
@balintpekker is right that this command only assumes one single space between word.
@MichaelFoukarakis's solution is more generic, as it supports variable numbers of spaces and tabs but it fails on the first line of the given sample because it has a trailing space, forcing you to issue a second (easy) command.
A substitution would certainly be more precise and generic at the same time but also more verbose:
:%s/\s\+\S\+\s\+\S\+\s\+\S\+\s*$
or:
:%s/\v\s+\S+\s+\S+\s+\S+\s*$
Or we could simply do it UNIX-style:
:%!cut -d' ' -f -4
another edit
While looking for a smarter way to use cut
I stumbled on this answer which mentions an overcharged version of cut
called cuts
. It can be used like this:
:%!cuts -D' ' -0-3
You can use visual block, but this won't work if the length of the words differs too much. It will however work for the example you posted. Move to the space after 6, and press Ctrl+v. Then press $ to jump to the end of the line and move down as many lines as you want to delete.
Not the best solution, but learning to do stuff like this regularly greatly increases your productivity.