There's a perl
module called Set::IntSpan which already does this (it was originally written in 1996 to collapse lists of article numbers for .newsrc files, which could be enormous).
There is also a similar module for python
called intspan, but I haven't used it.
Anyway, with perl and Set::IntSpan (and tr
to get the input data into comma-separated format, and tr
again to munge the output), this is trivial.
$ tr $'\n' ',' < input.txt |
perl -MSet::IntSpan -lne 'print Set::IntSpan->new($_)' |
tr ',-' $'\n,'
2,3
9,12
24
28,29
33
Set::IntSpan
is packaged for debian and ubuntu as libset-intspan-perl
, for fedora as perl-Set-IntSpan
, and probably for other distros too. Also available on CPAN, of course.