3

I have a file similar to this:

aaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccc
dddddddddddddddddddd


aaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccc
dddddddddddddddddddd


aaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccc
dddddddddddddddddddd


I would like to join them to this:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd

Until now I have done this by selecting blocks in (ctrl + v) and deleting them (x) and pasting them to the end of the first block (gg$p). This is very time consuming and I did not manage to get these things working in a macro.

How can I combine multiple blocks of lines?

Mehdi Nellen
  • 191
  • 3
  • 11

5 Answers5

5

I got the macro working:

qqgg5j^V4j$xgg$p9jV4kd
  • qq starts a macro called q
  • gg sets the startingpoint to the first line of the file
  • 5j goes down 5 lines (the start of the block below it)
  • ^V4j$ goes into column selection mode and selects the first block
  • x cut the content of the selection
  • gg$p paste it to the end of the first block
  • 9jV4kd delete the empty lines left after cutting

Typing in 2@q performs this action twice combining all lines

Mehdi Nellen
  • 191
  • 3
  • 11
  • 1
    You could perhaps simplify the macro by deleting the empty lines before starting it: :g/^$/d, or something similar. – muru Mar 14 '16 at 00:02
3

Another macro solution:

  • First go to the beginning of the first paragraph (in your example with 10G)
  • Then record macro: qqCtrl-Shit-V}$d5k$p0q
  • Reuse the macro with @q

The detail of the macro:

  • Ctrl-Shit-V start visual block mode
  • } select to the last line of the paragraph
  • $ select to the end of the line
  • d delete the selection
  • 5k go to the first line of the previous paragraph
  • $ got to the end of this line
  • p past the previously deleted paragraph
  • 0 go to the beginning of the line to be able to repeat the macro
statox
  • 49,782
  • 19
  • 148
  • 225
3

What you do is almost .. graphical, so I'd use the mouse!

(of course you need :set mouse+=a)

Select a block with the mouse, then Ctrl-v y to yank the selection in "control-block" mode (<- that's the "secret" sauce). Still using the mouse, place cursor on top right character of the 2nd block. Paste (p).

Repeat :D ... That's all!

Yes, it's probably not feasible for a macro, or a large number of repetitions, but how long a line do you want to make?

VanLaser
  • 9,700
  • 2
  • 24
  • 34
2

Here's another way:

Make sure the a register is empty

:let @a = ''

Match all lines starting with aa, and then append them to the a register with y (the capital A means append, rather than overwrite). After that delete the line with d.

:g/^aa/y A | d

Now we can paste this at the start of the buffer (or anywhere else you'd like):

1G"aP

And join them:

4gJ

Repeat for bbb, ccc, etc.

The last step is perhaps easier done as:

vnnngJ

Which starts visual mode with v, n to skip past the lines, and then J to join them. You could also press J a few times in a row...

or:

v/^bbb<Enter>kgJ

Which searches for /^bbb, this has the advantage that the last used search pattern is now "primed" for our next :g invocation, which can now read:

:g//y A | d

Not specifying a pattern will use the last used search pattern (i.e. the @/ register).

Martin Tournoij
  • 62,054
  • 25
  • 192
  • 271
2

The interesting thing is how to deal with movement. If the lines to join start with same characters you can do (automated with a macro):

qq*"aD''*"AD''$"apj0

where:

  1. qq record a macro
  2. *"aD'' move to the line whith next char like first char of the first line, put the line in the register "a" and delete
  3. *"AD'' like 2. but append the line to the register

  4. $"ap paste register "a" at the end of the first line

  5. j0 move to the start of the next line

Then repeat the macro:

3@q

and delete the empty lines:

:$d
Antonio
  • 287
  • 1
  • 8