169

For example, if I have four lines as follows:

the first line
the second line
the third line
the fourth line

I want to reverse them to

the fourth line
the third line
the second line
the first line

How could I do this in Vim?

Jichao
  • 7,940

6 Answers6

167

To reverse all the lines in a file,

:global/^/move 0

Abbreviated:

:g/^/m0

For an explanation see

:help 12.4

which also shows how to reverse just a range of lines.

icc97
  • 625
garyjohn
  • 36,494
139

Select the desired lines, hit !, and in the resulting prompt pipe the lines through tac a la :'<,'>!tac. See man tac for more details.

Rhys Ulerich
  • 1,499
47

On Mac OS X, tac does not exist, but you can use tail -r to the same effect:

:%!tail -r

This also works nicely for visual mode:

:'<,'>!tail -r

Excerpt from tail(1)'s manpage:

The -r option causes the input to be displayed in reverse order, by line. Additionally, this option changes the meaning of the -b, -c and -n options. When the -r option is specified, these options specify the number of bytes, lines or 512-byte blocks to display, instead of the bytes, lines or blocks from the beginning or end of the input from which to begin the display. The default for the -r option is to display all of the input.

10

For those more comfortable with Visual mode:
1. Identify the line number above the selection you want flipped using :set nu.
2. Shift-V to highlight selection you want flipped (visual mode).
3. :g/^/m <Line number from step 1>.

Note that in visual mode it will automatically show up as :'<,'>g/^/m <Line number> when you type in the command from 3.

This command works by moving the selection one line at a time into the line number that you give it. When the second item gets pushed into the line number given, it pushes the first down to line number + 1. Then the third pushes the first and second down and so on until the entire list has been pushed into the single line number resulting in a reverse ordered list.

horta
  • 477
  • 4
  • 10
8

A command :Rev[erse] and optional mappings for your vimrc, so you don't have to remember and perform the non-obvious steps of this recipe:

" Reverse the lines of the whole file or a visually highlighted block.
    " :Rev is a shorter prefix you can use.
    " Adapted from http://tech.groups.yahoo.com/group/vim/message/34305
command! -nargs=0 -bar -range=% Reverse
    \       let save_mark_t = getpos("'t")
    \<bar>      <line2>kt
    \<bar>      exe "<line1>,<line2>g/^/m't"
    \<bar>  call setpos("'t", save_mark_t)

nmap <Leader>r :Reverse<CR>
xmap <Leader>r :Reverse<CR>

(:xmap maps for Visual but not Select mode, as :help mapmode-x advises for mapping printable characters.)

(Based on: http://tech.groups.yahoo.com/group/vim/message/34305 )

4

Let' say you are at the line 3, hence we have a range 3 to 6. Just type.

:3,6g/^/m2