In Ed I can do a search to replace all blank lines as follows:
g/^$/d
This deletes all blank lines. But what if I wish to delete two or more blank lines and keep 1? For example:
Line 1
Line 2
Line 3
Becomes:
Line 1
Line 2
Line 3
In Ed I can do a search to replace all blank lines as follows:
g/^$/d
This deletes all blank lines. But what if I wish to delete two or more blank lines and keep 1? For example:
Line 1
Line 2
Line 3
Becomes:
Line 1
Line 2
Line 3
Adapted from the Vim Wiki:
ed -s file <<EOF
v/./.,/./-1j
w
q
EOF
v/./: select all lines that don't match the regex . (i.e., select all blank lines). Execute the following action on them:
.,/./-1j: the join command is applied from a selected line (.) up to the the line above the next non-blank line (/./-1).w q: save and quit. You could use %p Q instead to only display the output without modifying the file.Although equally valid, my original suggestion was more complicated:
printf '%s\n' 'g/^$/.,/./-1d\' 'i\' '' w q | ed -s file
This one uses two commands for a single global command (usually the command list consists of a single command), which requires prefixing newlines with backslashes for its command list.
g/^$/: select all blank lines.
.,/./-1d\: delete from the selected line (.) up to the line above the next non-blank line (/./-1). This would delete all blank lines, so'i\' '': insert a new blank line above.It is equivalent to use here-docs or Printf to feed Ed. Just pick the one you like best.
Reference: POSIX Ed.
Using an external command is a totally valid way to edit in ed, and assuming that all non-empty lines are unique when compared to their immediately surrounding lines (i.e. non-repeating), we could call uniq to remove the excess empty lines:
w
e !uniq %
We need to save our work with w first since uniq will read from the current file on disk. The e !somecommand command replaces the contents of the editing buffer with the output of somecommand, and uniq will remove duplicated consecutive lines in the named file. The % in the command will be replaced by the name of the current file. With our assumption at the start, this solves our issue by removing duplicated consecutive empty lines.