Vim - Adding empty line between lines

15

3

How do I insert a blank line between every non-blank lines?

eg. from

line 1
line 2
line 3

line 4
line 5

to

line 1

line 2

line 3

line 4

line 5

ayutheos

Posted 2013-05-07T04:33:47.713

Reputation: 223

Answers

1

Other way of doing is:

:%s/$/\r/g

$ is for end of line \r is adding new line g do it globally not just first occurrence

But this will add a line between blank lines too

vikramaditya234

Posted 2013-05-07T04:33:47.713

Reputation: 158

28

Vim's :g command is designed for exactly this sort of task; running a single action on every line which matches a particular pattern. Here's my answer:

:g/.\n\n\@!/norm o

The pattern I use is /.\n\n\@!/. Breaking that down into its component pieces:

  • . Matches any character in the line. (used to immediately discard any existing empty lines from consideration)
  • \n Matches a single \n at the end of the character above
  • \n\@! Fails the match if there's another \n immediately after the earlier \n.

(Check :h E59 for more information on \@! and similar match specifiers in regular expressions -- there are a couple others, too!)

So the :g command's regex has now selected every non-empty line which is terminated by a single newline, and which isn't followed by an empty line.

After the pattern in a :g statement comes the command to run on matching lines. In this case, I've told it to execute a normal mode command (abbreviated to norm), and the command to run is simply o, which inserts an empty line below the current line.

So taken together, the command finds every line which doesn't have an empty line beneath it, and adds one. And that's all there is to it! You might like to check the vim wiki's Power of G article for more fancy things you can do with :g (and it's negative sister, :v) -- it's one of those amazingly useful commands which you soon grow to rely on, and then miss terribly in editors which don't have it.

Trevor Powell

Posted 2013-05-07T04:33:47.713

Reputation: 515

1Precisely. I usually look for shorthands like :%norm o but it turns out this doesn't work as intended in the case of o. +1 – sehe – 2013-05-07T07:02:31.333

Type :%s/$/, then hit ^V, then hit Enter. – jpaugh – 2013-05-07T10:46:24.373

1@jpaugh Assuming that you mean :%s/$/<C-V><CR><CR> (to use common vim-folk encoding of keypresses), that approach just adds a newline after each line. That is, lines which are already separated by blanks (see Line 3 -> Line 4, in the example text) wind up getting extra blank lines. Original question was to avoid adding extra blank lines where they already existed in the starting text. – Trevor Powell – 2013-05-07T11:46:09.017

3

When I tested @NeilForester's global search and replace answer, I found that it missed every second intended replacement in consecutive non-blank lines if the lines only had one character in each. This appears to be due to the pattern starting to match on each occasion after the last character that it matched the previous occasion.

Using lookbehind and lookahead solves this problem and makes the regex a bit shorter too:

:%s/\n\@<!\n\n\@!/\r\r/g

Simon

Posted 2013-05-07T04:33:47.713

Reputation: 611

Thanks! This works, and it doesn't add more lines if I run the search again (if say, I added new lines into my file). – None – 2013-05-07T06:27:33.027

1Could you explain what each of the regex in the search pattern means? Looking at vim help, \n\@<!\n means any linebreak that's not right after another linebreak is that correct? But I couldn't understand what \n\@! means. I'd like to understand it so I can learn and apply it to other search patterns :) – None – 2013-05-07T06:32:19.560

Yes, \n\@<!\n means any linebreak that doesn't immediately follow another linebreak. \n\@! matches with zero width if the preceding atom (i.e. \n) does not match just before what follows. Try :help \@<! to see the documentation on this in vim. I – Simon – 2013-05-07T07:11:01.260

3

Another way:

%s/\(.\)\n\(.\)/\1\r\r\2/

Which means,

\(.\) match and capture a non-newline character,
\n    match a newline
\(.\) match and capture a non-newline character

replace with: first capture, double newlines, and the second capture.

For example, line1\nLine2 results in \1 = 1 and \2 = L.

perreal

Posted 2013-05-07T04:33:47.713

Reputation: 663

0

Correct me if I am wrong. I believe you use the letter k when in command mode to move down a line. Then enter insert mode and add the next line. Repeat as necessary? Hope this helps!

Nick Gerrer

Posted 2013-05-07T04:33:47.713

Reputation: 11

k moves up a line. j moves down a line. – Neil Forrester – 2013-05-07T04:38:24.757

Yes, Indeed it does. My mistake. Thanks Neil! – None – 2013-05-07T04:52:06.297

0

/[^\n]\n[^\n]
:map <F2> no<esc><F2>

Then press <F2>. That will search for two consecutive non-blank lines, and then add a line between them, repeatedly.

Edit:

Here's an alternative way to do it with a single, global search and replace:

:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g

Neil Forrester

Posted 2013-05-07T04:33:47.713

Reputation: 111

My file has lots of lines. Is there a way to do a regex search & insert blank line for the whole file? I've been looking at http://stackoverflow.com/questions/2673209/how-do-i-insert-a-blank-line-before-every-comment-eg-in-vim but couldn't grasp what all the regex commands mean.

– None – 2013-05-07T04:47:53.990

See my above edit for an alternative way to accomplish the same thing in a single command, and without a recursive mapping. The first way ought to work for the whole file though. – Neil Forrester – 2013-05-07T05:34:24.837

0

Try this command (16 characters):

:%!sed G|cat -s

kev

Posted 2013-05-07T04:33:47.713

Reputation: 9 972

Instead of attempting to "vimgolf" a short command, a little explanation of the rather obscure options used would be more helpful. – Ingo Karkat – 2013-05-07T08:37:16.850

0

I don't know how long is your file but one of the simplest method is type o in command mode. And in the next line .. This could be load to simple macro.

Demagog

Posted 2013-05-07T04:33:47.713

Reputation: 1