Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have some text-files I use to take notes in - just plain text, usually just using cat >> file. Occasionally I use a blank line or two (just return - the new-line character) to specify a new subject/line of thought. At the end of each sessions - before closing the file with ctrl-D - I typically add lots (5-10) blank lines (return-key) just to separate the sessions.

This is obviously not very cleaver, but it work for me for this purpose. I do however end-up with lots and lots of unnecessary blank lines, so I'm looking for a way to remove (most of) the extra lines. Is there a Linux-command (cut, paste, grep, ...?) that could be used directly with a few options? Alternatively, does anybody have an idea for a sed, awk or perl (well in any scripting-language really, though I'd prefer sed or awk) script that would do what I want? Writing something in C++ (which I actually could do myself), just seems like overkill...

Case #1: What I need is a script/command that would remove more than two (3 or more) consecutive blank lines, and replace them with just two blank lines. Though it would be nice if it also could be tweaked to remove more than one line (2 or more) and/or replace multiple blank lines with just one blank line.

Case #2: I could also use a script/command that would remove a single blank line between two lines of text, but leave multiple blank lines as is (though removing one of the blank lines would also be acceptable).

PS: Yes, I absolutely ought to learn advanced(?) sed and awk scripting, as well as perl... it's long overdue. But as I promised myself to do just that after reading a very good Linux-book back in 1995, I'm not that hopeful I will.

share|improve this question
    
possible duplicate of Replacing Multiple blank lines with a single blank line in vim / sed –  l0b0 Apr 17 '13 at 10:45
2  
@l0b0, that's a completely different question altogether (the other one was a vim one, and was to replace blank lines with one blank line). –  Stephane Chazelas Apr 17 '13 at 11:41
add comment

4 Answers

up vote 9 down vote accepted

Case 1:

awk '!NF {if (++n <= 2) print; next}; {n=0;print}'

Case 2:

awk '!NF {s = s $0 "\n"; n++; next}
     {if (n>1) printf "%s", s; n=0; s=""; print}
     END {if (n>1) printf "%s", s}'
share|improve this answer
    
+1 for awk instead of sed –  Rob Apr 17 '13 at 17:22
    
Since this use case is repeated frequently, I would suggest creating a script. –  ChuckCottrill Oct 10 '13 at 23:43
add comment

You can use uniq to collapse multiple instance of blank lines into one blank line, but it will also collapse lines which contain text if they are the same and below each other.

share|improve this answer
2  
+1 for using uniq in a way that's never occurred to me. –  Baard Kopperud Apr 17 '13 at 11:00
add comment

You can address Case #1 like this with GNU sed:

sed -r ':a; /^\s*$/ {N;ba}; s/( *\n *){2,}/\n\n/'

That is, collect empty lines in pattern space, and if there are more than three or more lines, reduce it to two lines.

To join single-spaced lines, as in Case #2, you can do it like this:

sed -r '/^ *\S/!b; N; /\n *$/!b; N; /\S *$/!b; s/\n *\n/\n/'

Or in commented form:

sed -r '
  /^ *\S/!b        # non-empty line
  N                # 
  /\n *$/!b        # followed by empty line
  N                # 
  /\S *$/!b        # non-empty line
  s/\n *\n/\n/     # remove the empty line
'
share|improve this answer
add comment

Case 1:

perl -i -ane '$n=(@F==0) ? $n+1 : 0; print if $n<=2'

Case 2:

perl -i -ane '$n=(@F==0) ? $n+1 : 0; print $n==2 ? "\n$_" : $n==1 ? "" : $_ '
share|improve this answer
    
+1 perl ftw! Awk is (probably) canonical for this, but (DRY) compels me to write scripts for use-cases that are repeated like this. –  ChuckCottrill Oct 10 '13 at 23:42
add comment

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.