5

I am looking for a solution of turning file A to file B, which requires merging two blank lines into one.

File-A:

// Comment 1
// Comment 2

// Comment 3


// Comment 4



// Comment 5

File-B:

// Comment 1
// Comment 2

// Comment 3

// Comment 4

// Comment 5

From this post, I know how to delete empty lines, I am wondering how to merge two consecutive blank lines into one.

PS: blank means that it could be empty OR there might be a tab or a space in the line.

Community
  • 1
  • 1
Daniel
  • 2,576
  • 7
  • 37
  • 51
  • Do you like to have one blank line between every line, even if there are three blank lines consecutive. Please give example output. – Jotne Jun 23 '14 at 19:36
  • I thought I could use a loop for 2+ blank lines situation, so I didn't ask that. You mean there is an answer for 2+ blank lines? – Daniel Jun 23 '14 at 19:44
  • OK My answer does what I thought you like to do :) – Jotne Jun 23 '14 at 20:09

6 Answers6

7
sed -r 's/^\s+$//' infile | cat -s > outfile

sed removes any whitespace on a blank line. The -s option to cat squeezes consecutive blank lines into one.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    This works, thanks. Could it be possible to do the edit "in-place"? – Daniel Jun 23 '14 at 19:19
  • 1
    +1; clever combination of tools, although the syntax is GNU `sed`-specific. A POSIX-compliant alternative: `sed 's/^[[:blank:]]\{1,\}$//' file | cat -s > outfile`. – mklement0 Jun 24 '14 at 01:51
  • 1
    @Daniel: You'll have to use the standard idiom for working around not being able to perform in-place updating: instead of `> outfile`, use `> /tmp/tmp.$$ && move /tmp/tmp.$$ infile`. – mklement0 Jun 24 '14 at 01:58
6

This might work for you (GNU sed):

sed '$!N;s/^\s*\n\s*$//;P;D' file

This will convert 2 blank lines into one.

If you want to replace multiple blank lines into one:

sed ':a;$!N;s/^\s*\n\s*$//;ta;P;D' file

On reflection a far simpler solution is:

sed ':a;N;s/\n\s*$//;ta' file

Which squeezes one or more blank lines to a single blank line.

An even easier solution uses the range condition:

sed '/\S/,/^\s*$/!d' file

This deletes any blank lines other than those following a non-blank line.

potong
  • 55,640
  • 6
  • 51
  • 83
4

Here is a simple solution with awk:

awk '!NF && !a++; NF {print;a=0}' file
// Comment 1
// Comment 2

// Comment 3

// Comment 4

// Comment 5

NF counts the number of fields; note that a line composed entirely of spaces and tabs counts as a blank line, too.
a is used to count blank lines, and if it's more than 1, skip it.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Jotne
  • 40,548
  • 12
  • 51
  • 55
1

This page might come handy. TL;DR as follows:

# delete all CONSECUTIVE blank lines from file except the first; also
# deletes all blank lines from top and end of file (emulates "cat -s")
sed '/./,/^$/!d'          # method 1, allows 0 blanks at top, 1 at EOF
sed '/^$/N;/\n$/D'        # method 2, allows 1 blank at top, 0 at EOF
jimm-cl
  • 5,124
  • 2
  • 25
  • 27
  • 1
    This fails if there are `spaces` and or `tabs`. OPs request `PS: empty could also mean that there might be a tab or a space in the line.` – Jotne Jun 23 '14 at 19:32
0

This should work:

sed 'N;s/^\([[:space:]]*\)\n\([[:space:]]*\)$/\1\2/;P;D' file
Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
0
awk -v RS='([[:blank:]]*\n){2,}' -v ORS="\n\n" 1 file

I had hoped to produce a shorter Perl version, but Perl does not use regular expressions for its record separator.

awk does not edit in-place. You would have to do this:

awk -v RS='([[:blank:]]*\n){2,}' -v ORS="\n\n" 1 file > tmp && mv tmp file
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 1
    A heads-up: Requires an `awk` implementation that recognizes regexes as record separators (non-POSIX), such as GNU `awk`. The trailing `\n\n` in the output is awkward. – mklement0 Jun 23 '14 at 22:40