sed '$n;h;N;/^\(.\).*\n\1/g;/\n/P;//!G;D' <in >out
sed script that will do it.
It works like this:
- If current line is the last, print it to standard out and end the script.
- If not, save a copy of current line to hold space.
- Then append the Next input line to pattern space.
- If the first char in pattern space is identical to the first char in the line just appended, overwrite pattern space with the saved hold-space copy.
- If not, then we'll still have a
\newline in pattern space, in which case we should Print only up to that point.
- If not, Get another copy of our held line appended to pattern space.
- Regardless, Delete up to the first newline in pattern space and start over from the top of the script with what remains.
Essentially, it works two lines at a time, Printing only the first when the first char in the second line doesn't match that of the first line, and recursively overwrites those which do with the first occurrence in a series. And so it can quickly and capably handle input of any size with minimal buffering and squeeze a first char match series of any size to only its first occurrence. It will work with real-time input or else with a file, but it doesn't ever need to read or store any more than a copy of the current line and the next.