sed '5,${s/^$//; t delete; b end; : delete; d; : end;}' temp_spec.rb
Edit 1:
I am supposed to explain this, thus...
This is unnecessarily complicated. I didn't know that address ranges are allowed within {}
. So I had to express "delete empty lines" differently. The core command is t
which is sed's way of if ... then
. T
would have been easier but is available for GNU sed only. I cite the man page:
t label : If a s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label; if label is omitted, branch to end of script.
I abuse the famous s
command. It shall not replace anything but test only whether the line is empty. So it replaces an empty line by an empty line (could use anything as replacement as the line is deleted anyway).
If s
has done a "replacement" then the line is empty. In that case the command d
shall be executed. Otherwise nothing is to be done. As t
does not jump in case of an s
action I need the branch command b
to jump to the end of the script. : label
are branch targets. Like goto
back then in the dark ages (when sed was invented... te-hee).
Another option would be to have s
"replace" all non-empty lines, making the s
more complicated but rest of the command easier:
sed '5,${s/^\(..*\)$/\1/; t end; d; : end;}' input
^..*$
means "non-empty line" and \1
means "the content of the first brackets".