I can remove the last 10 lines like this:
ex -sc '-9,d|x' f.txt
However, I would like to invert the selection, or remove all lines except the last 10. Is this possible?
Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It only takes a minute to sign up.Sign up to join this community
Here is a solution which comes from here. Note that might not be exactly what you're looking for since it's implies to use a visual (or normal) mode mapping instead of just an
The idea is to create the following mapping which will allow you to keep in your buffer only the visually selected lines:
vnoremap <key> :<C-U>1,'<-1:delete<CR>:'>+1,$:delete<CR>
The mapping can be decomposed like this:
:enter ex mode.
<C-U>empty the lines from the first one to the current one.
1,'<-1Specify the range from the first line of the file to the line before the start of current selection.
:delete<CR>delete the lines previously sectioned by the range.
:'>+1,$create a range from the end of the selection to the end of the line/
:delete<CR>delete the new range.
You can then visually select the last 10 lines (or whatever lines you want to keep) and press
<key> used in the mapping to delete all the line not selected.
Now based on this solution I have created the following function:
function! InvertRange(command) range execute (a:lastline+1) . ",$ " . a:command execute "1," . (a:firstline-1) . " " . a:command endfunction
You should provide a command as argument and a range and the function will apply this command on the lines which are not in the range. Note that here the range under the selection is treated first otherwise if you provide
"delete" as argument the line position will change and the deletion will not happened on the line you wanted.
An example call of the function is
:20,30 call InvertRange("delete")
Which will delete all lines excepted the ones between the 20th and the 30th.
Finally as a bonus here is a command that you can use to call the
InvertRange function more easily:
command! -range -nargs=1 -complete=command IR <line1>,<line2>call InvertRange(<f-args>)
The command accept a range (if no one is provided it takes the current line) and allows the completion on the ex commands. Thus you can use:
:20,30 IR delete
To call the
InvertRange function with
delete as a command to execute and the range
20,30 to invert.