33

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

Community
  • 1
  • 1
Just a learner
  • 24,222
  • 49
  • 140
  • 218
  • Try reading all the answers next time: http://stackoverflow.com/questions/922449/how-can-i-replace-mutliple-empty-lines-with-a-single-empty-line-in-bash/922499#922499 – OrangeDog Dec 23 '10 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. – Just a learner Dec 23 '10 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 Dec 23 '10 at 18:21
  • 1
    @barti_ddu: this will delete _all_ empty lines, rather than reduce them into one. – thkala Dec 23 '10 at 18:29

2 Answers2

61

Give this a try:

sed '/^$/N;/^\n$/D' inputfile
Dennis Williamson
  • 324,833
  • 88
  • 366
  • 429
  • +1 Anyway, your example is better, since it will process leading & trailing empty lines correctly, while mine will simply strip them. – barti_ddu Dec 23 '10 at 20:55
  • Matching newline at the beginning of the line is not necessary, simply matching newline is enough. – barti_ddu Dec 24 '10 at 01:56
  • would someone please explain the sed expression? – ThorSummoner May 15 '20 at 21:12
  • 1
    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 – ThorSummoner May 15 '20 at 21:30
  • 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` – ThorSummoner May 15 '20 at 21:34
2

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.

barti_ddu
  • 9,889
  • 1
  • 44
  • 51