Given a file with an even number of lines, how can one interleave the lines from the second half onto the first half? For example, from this:
a
b
c
1
2
3
To this:
a
1
b
2
c
3
One possible solution would be writing those halves to
separated files and then use the paste
utility.
:1,3w a | 4,6w b
:%!paste -d \\n a b
However, I'd like to find a short way of doing it within Vim — using native commands.
The :g
command is frequently used to iterate on lines and
perform some command. In this case it could be used to
iterate on the lines at the second half of the file, while
moving lines from the first half to their appropriate
relative locations with :m
.
Considering we have the cursor on the first line at the
second half, this line must be preceded by the first line
from the first half, so we can move it there with :1 m -1
(move line 1 to position -1, in relation to cursor). After
this, line 1 is now what should precede the second line from
the second half. It is thus a matter of moving the cursor
down and repeating this process, conveniently performed by
:g
. In short, first jump to the first line of the second
half with 50% and then:
:,$g/^/1m-1
As a command which takes a range of the full block to be interlaced (both halves) or defaults to the entire file:
command! -range=% Interleave execute 'keeppatterns'
\ (<line2>-<line1>+1)/2+<line1> ',' <line2>
\ 'g/^/<line1> move -1'
:Interleave
Note: :Interleave
uses :keeppatterns
to prevent the
search register and history from changing. :keeppatterns
requires Vim 7.4.083+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With