41

I know there is a similar question in SO How can I replace mutliple empty lines with a single empty line in bash?. But my question is can this be implemented by just using the sed command?

Thanks

4
  • Try reading all the answers next time: stackoverflow.com/questions/922449/…
    – OrangeDog
    Commented Dec 23, 2010 at 17:47
  • 3
    Actually I have read all the answers. The answer Clue Less and Can Berk Güder provided are just remove all empty lines, not the same as what I needed. Commented Dec 23, 2010 at 17:57
  • -i switch? sed -i '/^$/d' text.txt should work and as far as i've checked it is in answer list (besides -i option).
    – barti_ddu
    Commented Dec 23, 2010 at 18:21
  • 3
    @barti_ddu: this will delete all empty lines, rather than reduce them into one.
    – thkala
    Commented Dec 23, 2010 at 18:29

3 Answers 3

79

Give this a try:

sed '/^$/N;/^\n$/D' inputfile

Explanation:

  • /^$/N - match an empty line and append it to pattern space.
  • ; - command delimiter, allows multiple commands on one line, can be used instead of separating commands into multiple -e clauses for versions of sed that support it.
  • /^\n$/D - if the pattern space contains only a newline in addition to the one at the end of the pattern space, in other words a sequence of more than one newline, then delete the first newline (more generally, the beginning of pattern space up to and including the first included newline)
5
  • +1 Anyway, your example is better, since it will process leading & trailing empty lines correctly, while mine will simply strip them.
    – barti_ddu
    Commented Dec 23, 2010 at 20:55
  • Matching newline at the beginning of the line is not necessary, simply matching newline is enough.
    – barti_ddu
    Commented Dec 24, 2010 at 1:56
  • would someone please explain the sed expression? Commented May 15, 2020 at 21:12
  • 2
    expression: /.../ match lines via regexp, ^$ regex match empty line (beginning of line followed by end of line) N append next line to current line, so now we should have a blank line a newline and another blank line ; I didn't find anything about this in the manual, maybe this means "branch if line matches" eg "do the next command for double empty lines", /^\n$/ regex match empty line newline empty line and use D command, which I think deletes the selection even if it contains newlines Commented May 15, 2020 at 21:30
  • 1
    this also appears to work with the original input buffer and not with a post-substituted buffer? I cant seem to combine it like sed -e s,\ \+,,g -e /^\$/N\;/^\\n\$/D < data Commented May 15, 2020 at 21:34
4

You can do this by removing empty lines first and appending line space with G command:

sed '/^$/d;G' text.txt

Edit2: the above command will add empty lines between each paragraph, if this is not desired, you could do:

sed -n '1{/^$/p};{/./,/^$/p}'

Or, if you don't mind that all leading empty lines will be stripped, it may be written as:

sed -n '/./,/^$/p'

since the first expression just evaluates the first line, and prints it if it is blank.

Here: -n option suppresses pattern space auto-printing, /./,/^$/ defines the range between at least one character and none character (i.e. empty space between newlines) and p tells to print this range.

0
2

Since "empty lines" can contain "invisible" whitespaces, tabs, \f, \v, \r, etc.; in more general contexts we can use

sed -zE 's/([ \t\f\v\r]*\n){3,}/\n\n/g' inputfile
1
  • that's one is great! I was just looking for a solution to such case. Commented Jul 9 at 12:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.