Description
The first two scripts will retain all blank lines while the third one will remove them.
Raw Input Desired Output
 
(p1,l1)
(p1,l2)

(p2,l1) (p2,l2) (p2,l3) (p2,l4)
(p3,l1)
 
(p1,l1)(p1,l2)

(p2,l1)(p2,l2)(p2,l3)(p2,l4)
(p3,l1)
Script and Comments
Script1
[ 1] /^$/b
[ 2] :loop
[ 3] $!{
[ 4] N
[ 5] /\n$/!b loop
[ 6] }
[ 7] s/\n(.)/\1/g
Comments
  1. The Pattern Space is abbreviated to `PS'.
  2. The `-r' option of GNU sed must be used or the parentheses used in Step [7] must be escaped, that is, s/\n\(.\)/\1/g must be used instead.
  3. Command `b' without a destination label makes sed jump to the end of the script, print the contents of PS, and then start a new cycle.
  4. Once the first line of a paragraph has been read, the loop consisting of Steps [2] thru [6] will repeat until a blank line is met or the end of the datafile is reached.
  5. After Step [6], PS contains all lines of a paragraph and the following blank line. To make that paragraph become one line but retain the blank line, Step [7] is used to remove every newline character in PS except the trailing one.
Script2
[ 1] /^$/b
[ 2] :loop
[ 3] $!N
[ 4] s/\n(.)/\1/
[ 5] t loop
Comments
  1. When processing a paragraph, this script uses a different approach from the first one since
    • the first script does not remove newline characters until PS has the whole paragraph
    • while this script removes a newline character each time a line of the paragraph has been appended to PS.
  2. Steps [2] thru [5] constitute a loop which
    • appends the next line of a paragraph to PS via the command `N' of Step [3],
    • removes the newline character separating two adjacent lines of the same paragraph via Step [4].
    • If the line appended by Step [3] is a blank line (this implies that the end of a paragraph has been reached) or Step [3] did not perform (this implies that the end of datafile has been reached), the command `s' of Step [4] will fail and Step [5] will not be performed;
    • otherwise Step [5] will make sed branch to Step [2].
Raw Input Desired Output
 
(p1,l1)
(p1,l2)

(p2,l1) (p2,l2) (p2,l3) (p2,l4)
(p3,l1)
(p1,l1)(p1,l2)
(p2,l1)(p2,l2)(p2,l3)(p2,l4)
(p3,l1)
Script and Comments
Script1
[ 1] /^$/d
[ 2] :loop
[ 3] $!{
[ 4] N
[ 5] /\n$/!b loop
[ 6] }
[ 7] s/\n//g
Comments
  1. This script will remove all blank lines.