How can I replace multiple empty lines with a single empty line in bash?

RegexBash

Regex Problem Overview


I have a file that contains:

something



something else

something else again

I need a bash command, sed/grep w.e that will produce the following output

something

something else

something else again

In other words, I need to replace multiple blank lines with just a single blank line. grep/sed are line based. I've never found a BASH solution that would work on multi-line regex patterns.

Regex Solutions


Solution 1 - Regex

For BSD-derived systems (including GNU):

You just need cat with the -s option which causes it to remove repeated empty lines from its output:

cat -s

From man page: -s --squeeze-blank: suppress repeated empty output lines.

Solution 2 - Regex

I just solved this problem by sed. Even if this is a 7 year old question, someone may find this helpful, so I am writing my solution by sed here:

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

Solution 3 - Regex

grep -A1 . <yourfile> | grep -v "^--$"

This grep solution works assuming you want the following:

Input

line1

line2 line3

line4

line5

Output

line1

line2 line3

line4

line5

Solution 4 - Regex

Actually, if you replace multiple newlines with a single newline, the output would be:

something
something else
something else again

You can achieve this by:

sed /^$/d FILE

Solution 5 - Regex

A solution with awk, which replaces several blank lines with a single blank line:

awk 'BEGIN{bl=0}/^$/{bl++;if(bl==1)print;else next}/^..*$/{bl=0;print}' myfile

Solution 6 - Regex

Usually, if I find that sed can't do something I need, I turn to awk:

awk '
BEGIN {
    blank = 0;
}

/^[[:blank:]]*$/ {
     if (!blank) {
          print;
     }
     blank = 1;
     next;
}

{
     print;
     blank = 0;
}' file

Solution 7 - Regex

If someone want use perl

perl -00pe0 < file

will do the same, as cat -s :)

Solution 8 - Regex

Use awk:

awk '{ /^\s*$/?b++:b=0; if (b<=1) print }' file

Breakdown:

/^\s*$/?b++:b=0
    - ? :       the ternary operator
    - /^\s*$/   matches a blank line
    - b         variable that counts consecutive blank lines (b++).
                however, if the current line is non-blank, b is reset to 0.


if (b<=1) print
    print if the current line is non-blank (b==0)
          or if there is only one blank line (b==1).

By adjusting the regex, you can generalize it to other scenarios like squeezing multiple blank lines (">") in email: https://stackoverflow.com/a/59189823/12483961

Solution 9 - Regex

This uses marco's solution on multiple files:

for i in *; do FILE=$(cat -s "$i"); echo "$FILE" > "$i"; done

Solution 10 - Regex

Use python:

s = file("filename.txt").read()
while "\n\n\n" in s: s = s.replace("\n\n\n", "\n\n")
import sys
sys.stdout.write(s)

Solution 11 - Regex

Python, with regular expression:

import re
import sys
sys.stdout.write(re.sub('\n{2,}','\n\n', sys.stdin.read()))

Solution 12 - Regex

Super easy to do with vim. Just open the file and type the following:

:%s/\n\n\n*/\r\r/

That will reduce all blocks of more than 2 new lines to 2 new lines. Hope this helps!

Solution 13 - Regex

I take it that you'll probably want to remove lines that only have whitespace.

That can be done with:

sed /^[:space:]*$/d FILE

Solution 14 - Regex

Pipelining it to |uniq may be solution (if other than empty lines don't duplicate)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNick ZalutskiyView Question on Stackoverflow
Solution 1 - RegexmarcoView Answer on Stackoverflow
Solution 2 - RegexWKPlusView Answer on Stackoverflow
Solution 3 - RegexbiggusjimmusView Answer on Stackoverflow
Solution 4 - RegexCan Berk GüderView Answer on Stackoverflow
Solution 5 - RegexmouvicielView Answer on Stackoverflow
Solution 6 - RegexDan MouldingView Answer on Stackoverflow
Solution 7 - Regexjm666View Answer on Stackoverflow
Solution 8 - RegexShaoyunView Answer on Stackoverflow
Solution 9 - Regexuser879121View Answer on Stackoverflow
Solution 10 - RegexJonas KölkerView Answer on Stackoverflow
Solution 11 - RegexRobᵩView Answer on Stackoverflow
Solution 12 - RegexCarl SverreView Answer on Stackoverflow
Solution 13 - RegexClue LessView Answer on Stackoverflow
Solution 14 - RegexmateuszaView Answer on Stackoverflow