Raw Input Desired Output
==Paragraph-1 Line 1===
==Paragraph-1 Line 2===
==Paragraph-1 Line 3===


==Paragraph-2 Line 1===
==Paragraph-2 Line 2===
==Paragraph-2 Line 3===

==Paragraph-3 Line 1===
==Paragraph-1 Line 1===
==Paragraph-2 Line 1===
==Paragraph-3 Line 1===
Script and Comments
Script1
[ 1] /./!d
[ 2] p
[ 3] :loop
[ 4] $d
[ 5] N
[ 6] /\n$/d
[ 7] s/.*\n//
[ 8] b loop
Comments
  1. 'Pattern space' and 'hold space' are abbreviated to 'PS' and 'HS', respectively.
  2. With Step [1], sed will delete blank lines and start a new cycle.
  3. When the first line of a paragraph is found, what we have to do is
    • Print it (Step [2]).
    • Skip the remaining lines of the paragraph
    .
  4. Steps [3] through [8] constitute a loop. This loop will
    • Append next line if it exists (Step [4] and [5]).
    • If the newly appended line is a blank one, '\n$' will match. This implies that the end of a paragraph is reached. We just discard the contents of PS and start a new cycle.
    • Otherwise, we delete the first line of PS and start next iteration.
Script2
[ 1] /./!d
[ 2] p
[ 3] :loop
[ 4] $!N
[ 5] s/.*\n\(.\)/\1/
[ 6] t loop
[ 7] d
Comments
  1. This is a refined version of Script1
  2. Consider the following two cases:
    • When the current line is the last one of the datafile, since command 'N' in Step [4] was not executed, PS will not contain a newline character.
    • When the first blank line following a paragraph is appended, PS will NOT match '.*\n.' since no character next to the newline exist.
    In these two cases, since no substitution will be made by Step [5], sed will not perform the conditional branch in Step [6], but perform Step [7].
Script3
[ 1] /^$/d
[ 2] p
[ 3] :loop
[ 4] $!N
[ 5] /\n./!d
[ 6] g
[ 7] b loop
Comments
  1. This script differs from Script2 in Step [5] thru Step [7].
  2. In Step [5], PS may contains
    1. Only one line, this implies that the end of file is reached since command 'N' in Step [4] was not performed.
    2. Two lines, where the second line is a blank one. This implies that the end of a paragraph is reached.
    3. Two lines, where the second line is not a blank one.
    Step [5] will discard lines of the first two cases.
  3. In Step [6], the content of PS is no longer needed, we use command 'g' to overwrite PS with the contents of HS, which is empty.