How to remove empty lines except of one

classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|

How to remove empty lines except of one

meino.cramer
Hi,

(using vim v.:7.3.584 under Gentoo-Linux with most features set on)

I tried things like

:s/^\r\r\r/\r/g

but with no success...

How can I reduce a bunch of empty lines to one single empty line?

Best regards,
mcc



--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Tim Chase
On 07/04/12 20:58, [hidden email] wrote:
> I tried things like
>
> :s/^\r\r\r/\r/g
>
> but with no success...

For some reason (legacy?), Vim uses \n on the left side and \r on
the right side, so you want something like

  :%s/\n\{2,}/\r

optionally tweaking the "2" and the number of "\r"s for your
particular use-case

-tim


--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Chris Jones-44
On Wed, Jul 04, 2012 at 10:52:47PM EDT, Tim Chase wrote:

> For some reason (legacy?), Vim uses \n on the left side and \r on the
> right side,

Ah.. good one.. baffled me for ages and always had something more urgent
to do.. never got a chance or remembered to look into it.. and kicked
myself later when I ran into it again..

Thanks for sharing..!

> so you want something like

>   :%s/\n\{2,}/\r

> optionally tweaking the "2" and the number of "\r"s for your
> particular use-case

With the eol that terminates non-empty lines, shouldn't it be¹:

| :%s-\n\{3,\}-\r\r-g

?

CJ

¹ And possibly also adding ‘\s\{1,\}’ or ‘\s*’ for white space..

--
HOW ARE YOU GENTLEMEN?

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Tim Chase
On 07/04/12 23:11, Chris Jones wrote:
> On Wed, Jul 04, 2012 at 10:52:47PM EDT, Tim Chase wrote:
>>   :%s/\n\{2,}/\r
>
>> optionally tweaking the "2" and the number of "\r"s for your
>> particular use-case
>
> With the eol that terminates non-empty lines, shouldn't it be¹:
>
> | :%s-\n\{3,\}-\r\r-g

It might be slightly more efficient, as replacing the "2" case with
\r\r is a NOOP.

As for blank-ish lines (containing just whitespace), it might become
something like

 %s/^\(\s*\n\)\+/\r

-tim


--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

gthm159
On Thu, Jul 5, 2012 at 4:24 PM, Tim Chase wrote:
As for blank-ish lines (containing just whitespace), it might become
something like

 %s/^\(\s*\n\)\+/\r


I added this to my .vimrc as:

command RemoveMultipleBlankLines %s/^\(\s*\n\)\+/\r

Now ":RemoveMultipleBlankLines" works like it should except when my file has a blank line at the very end.
In this case, I get 2 blank lines at the end.
Any idea how I can prevent that?

- Gautam

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Benjamin Fritz
On Thursday, July 5, 2012 7:15:43 AM UTC-5, Gautam wrote:

> On Thu, Jul 5, 2012 at 4:24 PM, Tim Chase wrote:
> <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">As for blank-ish lines (containing just whitespace), it might become
>
>
>
> something like
>
>
>
>  %s/^\(\s*\n\)\+/\r
> <font color="#888888">
> </font></blockquote>
>
> </div>
> I added this to my .vimrc as:</div>
>
> </div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">
>
>
>
> command RemoveMultipleBlankLines %s/^\(\s*\n\)\+/\r</div>
>
> </div></div></blockquote>Now &quot;:RemoveMultipleBlankLines&quot; works like it should except when my file has a blank line at the very end.
> In this case, I get 2 blank lines at the end.</div>
>
>
> Any idea how I can prevent that?</div>
>
> </div>
> - Gautam</div>
>
> </div>

This replacement works for me:

%s/^\_s\+\n/\r

I'm not actually sure why your version doesn't work, but I see the same behavior.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Tim Chase
On 07/05/12 10:12, Ben Fritz wrote:
> This replacement works for me:
>
> %s/^\_s\+\n/\r

With the (what I'd consider beneficial) side-effect of also removing
trailing whitespace from lines.

-tim


--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Tony Mechelynck
In reply to this post by meino.cramer
On 05/07/12 03:58, [hidden email] wrote:

> Hi,
>
> (using vim v.:7.3.584 under Gentoo-Linux with most features set on)
>
> I tried things like
>
> :s/^\r\r\r/\r/g
>
> but with no success...
>
> How can I reduce a bunch of empty lines to one single empty line?
>
> Best regards,
> mcc
>
>
>

In addition to all that has already been said, maybe (untested)

        :%s/^\n*$/\r/

would work too? (replacing any number of line breaks, as many as
possible, between a start-of-line and an end-of-line, by one line break).

One of the good things with Vim is that often there are many solutions
to a single problem.


Best regards,
Tony.
--
GUARD #1:  What, ridden on a horse?
ARTHUR:    Yes!
GUARD #1:  You're using coconuts!
ARTHUR:    What?
GUARD #1:  You've got two empty halves of coconut and you're bangin' 'em
            together.
                                   The Quest for the Holy Grail (Monty
Python)

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

gthm159
In reply to this post by Tim Chase

On Thu, Jul 5, 2012 at 10:47 PM, Tim Chase <[hidden email]> wrote:
On 07/05/12 10:12, Ben Fritz wrote:
> This replacement works for me:
>
> %s/^\_s\+\n/\r

With the (what I'd consider beneficial) side-effect of also removing
trailing whitespace from lines.


I'd consider that beneficial as well, except that it doesn't remove the trailing whitespace in my case.

I still have to use
%s/\s\+$//
to remove trailing whitespaces.

One command to do both - get rid of multiple blank lines and trailing whitespace - would be super!

- Gautam

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Benjamin Fritz
On Friday, July 6, 2012 12:30:09 AM UTC-5, Gautam wrote:

> On Thu, Jul 5, 2012 at 10:47 PM, Tim Chase <[hidden email]> wrote:
> On 07/05/12 10:12, Ben Fritz wrote:
> > This replacement works for me:
> >
> > %s/^\_s\+\n/\r
>
> With the (what I'd consider beneficial) side-effect of also removing
> trailing whitespace from lines.
>
>
> I'd consider that beneficial as well, except that it doesn't remove the
> trailing whitespace in my case.
>
> I still have to use
> %s/\s\+$//
> to remove trailing whitespaces.
>
> One command to do both - get rid of multiple blank lines and trailing
> whitespace - would be super!
>

The command I gave doesn't remove trailing whitespace on non-empty lines
because of the ^ anchor in the pattern. Without it, it removes trailing
whitespace, but also removes ALL empty lines instead of leaving one empty
line behind.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

rockybalboa4
In reply to this post by meino.cramer

Dnia 5 lipca 2012 3:58 [hidden email] napisał(a):


Hi,

(using vim v.:7.3.584 under Gentoo-Linux with most features set on)

I tried things like

:s/^\r\r\r/\r/g

but with no success...
 
cip <ESC>

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Tim Chase
On 07/08/12 15:54, rockybalboa4 wrote:
> I tried things like
> :s/^\r\r\r/\r/g

As I mentioned earlier in the thread, for some (historical?) reason,
Vim uses \n on the left side and \r on the right side, so you want

  s/^\n\n\n/\r/g

-tim


--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Chris Jones-44
In reply to this post by Tim Chase
On Thu, Jul 05, 2012 at 06:54:44AM EDT, Tim Chase wrote:

Hello Tim, not replying to anybody in particular..

> It might be slightly more efficient, as replacing the "2" case with
> \r\r is a NOOP.
>
> As for blank-ish lines (containing just whitespace), it might become
> something like
>
>  %s/^\(\s*\n\)\+/\r

I had a bit more time to look into this over the weekend and there's
something I don't understand regarding the way Vim handles the end of
buffer condition.

Here's one particular regex I came up with:

----------------------------------------------------------------------
/\(\%^\|\S\n\)\@<=\(\_^\s*\n\)\{2,\}\(\%$\|\S\)\@=
----------------------------------------------------------------------

This appears to do what I have in mind when used in a _search_ command,
note the initial ‘/’.

What this is supposed to match:

- a zero-length alternative: either start of buffer or any non
  white-space character followed by a new line

- two or more empty lines, each optionally containing white space

- another zero-length alternative: either end of buffer or a non
  white-space character.

What I'm trying to do is to match each group of more than two empty
lines once and once only - if you have a block of ten empty lines it
will match once.. When you hit ‘n’ the cursor jumps to the first line of
the next block.

Naturally, the regex is not meant to be efficient, smart, abstemious,
etc.. just a literal translation of my pseudo-code.

Anyway, I tested it on the following file/buffer:

--------------------------- start of file ----------------------------
1  |
2  |
3  |aaaa  
4  |  
5  |cccc
6  |
7  |
8  |dddd
9  |
10 |
11 |    
12 |
13 |
14 |
15 |asdfasdf
16 |
17 |
18 |
19 |asdf  asdf  
20 |  asdf
21 |
22 |asfd
23 |
24 |
25 |
---------------------------- end of file -----------------------------

line 1-2   : ‘^$’              (empty lines)
line 3     : ‘aaaa\n’          (four a's + eol)
line 4     : ‘  /n’            (two spaces + eol)
line 5     : ‘cccc\n’          (four c's + eol)
line 6-7   : ‘^$’              (empty lines)
line 8     : ‘dddd\n’          (four d's + eol)
line 9-10  : ‘^$’              (empty lines)
line 11    : ‘\t   \n’         (one tab, three spaces + eol)
line 12-14 : ‘^$’              (empty lines)
line 15    : ‘asdfasf\n’       (asdfasdf + eol)
line 16-18 : ‘^$’              (empty lines)
line 19    : ‘asdf  asdf  \n’  (asdf, 2 spaces, asdf, 2 spaces + eol)
line 20    : ‘  asdf\n’        (2 spaces, asdf, + eol)
line 22    : ‘asfd\n’          (asfd + eol)
line 23-25 : ‘^$’              (empty lines)

If I set hlsearch and search for text matching the above regex, five
blocks are (correctly) highlighted: 1-2, 6-7, 9-14, 16-18, and 23-25.

If I repeatedly hit the ‘n’ key, the cursor jumps to line 1, line 6,
line 9, line 16, line 23... and wraps around back to line 1, line 6,
line 9.. etc.

But when I proceed to _substitute_ all the matched blocks by a single
empty line:

:%s//\r

.. everything works as planned, preserving trailing white space, except
for the last three lines: they are replaced by two empty lines instead
of one. As if the last line in the file/buffer was somehow excluded from
the match.

So, is my regex not doing what I think it does¹, or is there something
‘special’ about the last line in a Vim buffer²?

No big deal... but if someone can figure out what's happening, I'd be
curious of their explanations.

Thanks,

CJ

¹ Plausible, but if I get rid of my two zero-length matches and I use
  the simpler ‘/(\_^\s*\n\)\{2,\} .. I also get my matches via the ‘/’
  command but the substitute ‘:%s’ command still leaves me with two
  empty lines at the end of the file.

² I saw other oddities, for instance when I add a line containing white
  space at the end of the sample file, the regex no longer matches. As
  a result, a block of empty lines at end of file is left untouched.
  I also noticed that Ben Fritz's suggestion earlier in this thread
  (‘%s/^\_s\+\n/\r’) has exactly the same ‘limitation’.


--
AHH! The neurotic monkeys are after me!

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Chris Jones-44
Here's a pared down version illustrating the problem:

| :%s-\(\%^\|.*\S\+.*\n\)\zs\(^\s*\n\)\{2,\}-\r

Before:

-------------------------------------------------------------------------
1 |
2 |
3 |asdf
4 |
5 |
-------------------------------------------------------------------------

After:

------------------------------------------------------------------------
1 |
2 |asdf
3 |
4 |
------------------------------------------------------------------------

Even though the regex matches, the substitute command fails to collapse
the two empty lines at the end of the buffer.

ibid. Ben Fritz' more efficient approach:

| :%s-^\_s\+\n-\r

Any thoughts..?

CJ

--
Mooo Canada!!!!

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Bee-16
This will collapse multiple blank lines,
remove trailing white space, and
leave only one blank line at the end of file.

%s-\_s\+$-\r

Bill

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Benjamin Fritz
On Tuesday, July 17, 2012 7:27:42 PM UTC-5, Bee wrote:
> This will collapse multiple blank lines,
> remove trailing white space, and
> leave only one blank line at the end of file.
>
> %s-\_s\+$-\r
>
> Bill

But this one fails to collapse the blank lines at the *beginning* of the file! I don't see what's special about the beginning of the file which would prevent it from matching.

I don't know whether this is a bug, or if we all have a subtle misunderstanding of \_s.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Chris Jones-44
On Wed, Jul 18, 2012 at 11:19:30AM EDT, Ben Fritz wrote:
> On Tuesday, July 17, 2012 7:27:42 PM UTC-5, Bee wrote:

> > This will collapse multiple blank lines, remove trailing white
> > space, and leave only one blank line at the end of file.

> > %s-\_s\+$-\r
> >
> > Bill

> But this one fails to collapse the blank lines at the *beginning* of
> the file! I don't see what's special about the beginning of the file
> which would prevent it from matching.

Bee's regex includes the new line character that terminates the
non-empty line just before a sequence of empty lines, AND somehow¹
excludes the last empty line of the sequence.

This makes it work at the end of the buffer: it replaces the last
non-empty line's eol + the following empty lines minus one by one eol.

If you forget about the notion of buffer for a second and reason as if
the buffer were a string:

asdf\n\n....\n\n  -> asdf\n\n            
    |--------| ^
     |         |
     |         .____ ignored by regex
     |
     ._______  matched and replaced by ‘\r’

Which give you:

asdf\n\n
    ^  ^
    |  |
    |  .______ last line in the buffer
    |
    ._________ what the regex matched and was replaced


Now the problem is that at the start of the buffer you do not have
a previous non-empty last line:

\n\n                  
^ ^
| |
| .____ ignored
|
.______ match

The first ‘\n’ is therefore replaced by a ‘\n’ giving:

\n\n -> \n\n

> I don't know whether this is a bug, or if we all have a subtle
> misunderstanding of \_s.

That's been my point all along. Your solution or Bee's are fine because
they do the job that matters.. Nobody really cares about empty lines at
start or end of buffer.. and if they do.. they can remove them manually.

The problem is that a bunch of regex's that should match do not.. or do
match when used as part of a search command but do  not when used in
a substitute command.

But don't take my word for it.. I only did a regex tutorial a couple of
months ago.. -)

CJ

¹ I haven't figured it out but it looks like the ‘$’ anchor is what
  causes this..

--
Oh My God!!! Larry is back!

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Benjamin Fritz
In reply to this post by Bee-16
On Tuesday, July 17, 2012 7:27:42 PM UTC-5, Bee wrote:
> This will collapse multiple blank lines,
> remove trailing white space, and
> leave only one blank line at the end of file.
>
> %s-\_s\+$-\r
>
> Bill

I found the problem with this one. :help /$ indicates that the $ is zero-width, so the end of line is not included in the match, therefore on the two blank lines at the beginning of the file, only the first is included in the match.

So, this works exactly as I think it should:

%s-\_s\+\n-\r

Note this is almost identical to my first proposed solution, except that it is missing the beginning of line anchor. I'm not sure what makes it fail with the ^ in place.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Chris Jones-44
On Wed, Jul 18, 2012 at 03:46:45PM EDT, Ben Fritz wrote:
> On Tuesday, July 17, 2012 7:27:42 PM UTC-5, Bee wrote:
> > This will collapse multiple blank lines,
> > remove trailing white space, and
> > leave only one blank line at the end of file.
> >
> > %s-\_s\+$-\r
> >
> > Bill

> I found the problem with this one. :help /$ indicates that the $ is
> zero-width, so the end of line is not included in the match, therefore
> on the two blank lines at the beginning of the file, only the first is
> included in the match.

> So, this works exactly as I think it should:
>
> %s-\_s\+\n-\r

The problem is that this regex only works for blocks of empty lines at
the beginning and end of the buffer: it replaces blocks of empty lines
separated by non-empty lines (the more general case) including the eol
that terminates the last non-empty line by a single ‘\r’. The result is
that these blocks are not replaced by a single empty line but rather..
as seen by the user.. by nothing. IOW, all empty lines except the ones
at the beginning and end of buffer are not collapsed.. they disappear.

One could imagine that this could be addressed by adding and extra ‘\r’:

| %s-\_s\+\n-\r\r

But then (obviously) this leaves two empty lines both at the beginning
and the end of the buffer.

> Note this is almost identical to my first proposed solution, except
> that it is missing the beginning of line anchor. I'm not sure what
> makes it fail with the ^ in place.

I feel that mixing (zero length) anchors such as ‘^’ and ‘$’ with actual
one character representations such as ‘\n’ or ‘\_.’ tends to confuse the
issue. With more typical regex processing where the input is a string
rather than an editor such as Vim's buffer, the only anchors are the
start of string and end of string..

What Vim does with ‘^’ or ‘$’ especially when they are part of an atom
that gets repeated via \+ ..  \{2,\} .. etc. is anybody's guess..

But again, I'm NOT particularly interested in finding a regex that
actually does the job (despite my remark regarding anchors, I like Bee's
effort because it's the most compact of them all and does the part of
the job that matters in real life) .. I don't remember in 5-6 years
using Vim I have ever needed to collapse multiple empty lines..

I am more curious as to why the various regexes that I tried to put
together actually do not work, this one for instance:

| %s-\(\%^\|.*\S\+.*\n\)\zs\(^\s*\n\)\{2,\}-\r

Or rather why they appear to work¹ when I use them in a search command,
but fail on the last line of the buffer when I use them in a substitute
command.

Thanks,

CJ

¹ I set incsearch and hlsearch to visualize what actually matches and
  move the cursor around the buffer.. I guess the highlighting could be
  buggy in corner case circumstances.. perhaps I should look into
  writing a function that grabs the actual match as seen by Vim
  internally and echoes it back to the terminal.

--
AHH! The neurotic monkeys are after me!

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: How to remove empty lines except of one

Bee-16
In reply to this post by Benjamin Fritz


On Jul 18, 12:46 pm, Ben Fritz <[hidden email]> wrote:

> On Tuesday, July 17, 2012 7:27:42 PM UTC-5, Bee wrote:
> > This will collapse multiple blank lines,
> > remove trailing white space, and
> > leave only one blank line at the end of file.
>
> > %s-\_s\+$-\r
>
> > Bill
>
> I found the problem with this one. :help /$ indicates that the $ is zero-width, so the end of line is not included in the match, therefore on the two blank lines at the beginning of the file, only the first is included in the match.
>
> So, this works exactly as I think it should:
>
> %s-\_s\+\n-\r
>
> Note this is almost identical to my first proposed solution, except that it is missing the beginning of line anchor. I'm not sure what makes it fail with the ^ in place.

osx terminal vim 7.3.584

%s-\_s\+\n-\r

Removes ALL blank lines,
rather than collapsing multiple blank lines into one 'blank' line.

I still want one blank line between 'paragraphs'.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
12