Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
2  
Relevant: stackoverflow.com/questions/10760326/… – FDinoff Mar 14 at 4:41
up vote 5 down vote accepted

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

share|improve this answer
1  
You could perhaps simplify the macro by deleting the empty lines before starting it: :g/^$/d, or something similar. – muru Mar 14 at 0:02

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
share|improve this answer

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?

share|improve this answer

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).

share|improve this answer
    
You could use gJ instead of J to prevent Vim from inserting spaces. – Jair Lopez Mar 17 at 2:12
    
@JairLopez Ah yes, I forgot about that. Thanks! – Carpetsmoker Mar 22 at 10:05

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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.