deleting some empty lines with sed

Tom Christiansen tchrist at convex.COM
Sun Apr 28 07:12:12 AEST 1991


>From the keyboard of datpete at daimi.aau.dk (Peter Andersen):
:I have some source-files that I produce documentation from.
:
:I use sed to make a few changes to the text. I have figured
:most of it out, but I have one problem remaining:
:If two or more blank lines appear, I want to remove all but
:one of these.
:
:I have tried the following sed script
:
:    s^ *$//p
:1,$ N
:    s/\(\n\n\)\n*/\1/gp
:
:but it didn't work.

You need to set up a look with labels and branches.  I see that as I type
this another poster has given you a sed solution, so I won't post my
crufty version of the same.

Something you can't do is use \n on the RHS of the expression, nor can you
use ^ or $ with \n.  Well, maybe *you* can, but I sure couldn't.   Maybe
that I even want to do these things shows that I've been doing more perl
than sed, but so it goes.

:Does anyone have a way of doing this, perhaps using something
:else but sed. I'm not a perl-guru, but if its possible in perl
:I'd like to hear about that too.

Well, your code isn't quite doing what your description is asking
for, since it seems to be trying to trim two or more newlines down to 
just one, but I'll assume you are looking for the equivalent 
of a `cat -s', but lines with all blanks count as blank lines.

One way you could approach it in perl is via brute force: you could
suck in the whole file (as you seemed to have been trying to do in sed)
and then perform your substitution:

    #!/usr/bin/perl
    undef $/;  			# undefine input record separator
    $_ = <>; 			# read entire input stream into pattern space
    $* = 1; 			# make ^ and $ work multi-linedly
    s/^([ \t]*\n)+/\n/g; 	# compress whitespace+newlines --> \n
    print;			# print pattern space

This is pretty easy to code, but will eat up a lot of memory if you have
a big file, since it needs to hold the entire file in memory at one time.
Instead, you could keep a state variable around that indicated whether the
last line had been blank.  We'll use $saw_blanks to mean whether the last
line was blank.  

    #!/usr/bin/perl -n 	
    next if /^\s*$/ && $was_blanks;
    s/^\s*$/\n/; 
    print;				
    $was_blanks = /^$/;		

In fact, now that I stare at it, I could have put used a pattern match
*and* a substitute, but instead I'll bunch them together.

    #!/usr/bin/perl -n 	
    next if s/^\s*$/\n/ && $was_blanks;
    print;				
    $was_blanks = /^$/;		

--tom



More information about the Comp.unix.shell mailing list