69

Question more or less says it all. I'm aware that /^$/d will remove all blank lines, but I can't see how to say 'replace two or more blank lines with a single blank line'

Any ideas?

6 Answers6

78

If you aren't firing vim or sed for some other use, cat actually has an easy builtin way to collapse multiple blank lines, just use cat -s.

If you were already in vim and wanted to stay there, you could do this with the internal search and replace by issuing: :%s!\n\n\n\+!^M^M!g (The ^M is the visual representation of a newline, you can enter it by hitting Ctrl+vEnter), or save yourself the typing by just shelling out to cat: :%!cat -s.

Caleb
  • 70,105
28

Use \n to indicate a newline in the search pattern. Use Ctrl+M in the replacement text, or a backreference. See :help pattern and :help sub-replace-special (linked from :help :s).

%s/\(\n\n\)\n\+/\1/
  • Can you please explain how does the search pattern? – Sagar Jain Sep 22 '15 at 07:14
  • @sjmp Requirement: replace two or more blank lines with a single blank line. Implementation: replace three or more consecutive newlines with just two newlines. See the manual for an explanation of the constructs used in the command. – Gilles 'SO- stop being evil' Sep 22 '15 at 08:21
  • But why do you need to use a group when its contents are fixed? – Sabuncu Nov 23 '17 at 18:01
  • 1
    @Sabuncu You don't need to use a group. But why not use a group? Here, I used a group because you can't copy-paste a command with a newline in the replacement text: you need to insert a literal Ctrl+M character, \n doesn't work in the replacement text. – Gilles 'SO- stop being evil' Nov 23 '17 at 19:24
  • Now I understand, thank you for taking the time to answer. – Sabuncu Nov 23 '17 at 19:52
  • I added the map nnoremap <Leader>x :%s/\(\n\n\)\n\+/\1/gc<CR> to my .vimrc; thanks coming up with the regex. Yours is much cleaner than the accepted answer. – Luke Davis Feb 09 '18 at 11:24
  • to make it easier to read we can use the 'very magic' flag \v as well: %s/\v(\n\n)\n+/\1/ – cmaceachern Oct 28 '22 at 16:01
11

If in Vim, just do this:

:%!cat -s

The -s flag for cat squeezes multiple blank lines into one.

domi91c
  • 361
coanor
  • 363
  • 4
    You might want to add a little detail around how this works, even if it is just a quote from the man page. – jasonwryan Nov 21 '12 at 05:22
  • Didn't work on windows 7 – user674669 Dec 02 '17 at 02:31
  • @user674669, ! will execute a shell command. cat is a Unix shell command, the equivalent command in Windows is type, but it does not condenses empty lines. Look for the other answers that use the substitute command (s) – Thiago Chaves Jun 24 '22 at 17:28
1

Using Perl:

perl -00 -pe ''

-00 command line option turns paragraph slurp mode on, meaning Perl reads text paragraph by paragraph rather than line by line.

Majid Azimi
  • 3,098
0

With sed (GNU sed) 4.2.2:

sed -r '
  /^\s*$/ { 
    # blank line
:NEXT
    N # append next line to pattern space - if none, autoprint PS and exit
    s/^\s*$\n^\s*$//g;t NEXT # if 2 blank lines, clear PS and loop to NEXT
  }
  # else, autoprint PS and next/exit
' < $MYFILE
-5

I know this is silly code, but I wanted to solve this issue in less than 10 min, and it worked

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done