use strict; my @names = sort map { chomp; $_ } ; my $len = 2; # adjust to suit your taste my @bucket; FILL: { my $prefix = common_prefix(@bucket, $names[0]); if (length $prefix >= $len) { push @bucket, shift @names; } else { print common_prefix(@bucket),"\n"; print join("\n", map { "-- $_" } @bucket), "\n"; @bucket = (); }; redo FILL while (@names) }; print common_prefix(@bucket) if @bucket; =head2 C<< common_prefix LIST >> Extracts the common prefix out of a list of strings. The strings may not contain the character C<\x00> because I'm lazy. =cut sub common_prefix { local $" = "\x00"; "@_" =~ m!^([^\x00]*)[^\x00]*(\0\1[^\x00]*)*$!sm or die "Internal error: '@_' does not match the RE"; $1; }; __DATA__ U2 - October U2 - Rattle and Hum U2 - The Joshua Tree Talking Heads - Sand In The Vaseline - Disc 1 Talking Heads - Sand In The Vaseline - Disc 2