Isso é bastante difícil com um único passe, e ainda mais difícil se você não assumir que o início precisa ser o mesmo.
Você pode escrever um script perl que corresponda a expressões regulares em relação a linhas anteriores, como:
my @words_on_line = split(/ /, $current_line);
my $i = 0; my $substring = ''; my $expression = '';
do {
$expression = join(' ', $words_on_line[0..$i++]);
if ($previous_line =~ m/^$expression/) {
$substring = $expression;
}
} until ($substring ne $expression);
Então, você também precisa verificar a próxima linha e potencializar reduzir a correspondência de substring, por exemplo, quando você tem
FOO a b c
FOO a b
FOO d
A primeira correspondência (de 2 para 1) forneceria FOO a b
, mas comparando abaixo, você só receberia FOO
.
O que se resume a: você precisa armazenar em buffer suas linhas até obter uma linha sem correspondência. Então, ao invés de imprimir, você faria algo como
unless ($substring) {
push @buffer, $current_line;
foreach (@buffer) {
unless (m/$substring/) {
$buffer_substring = $substring;
}
}
} else {
print scalar @buffer, " $buffer_substring\n";
}
E então você só combinaria isso.
Se não for "o primeiro ponto de partida comum desde o início da linha", você terá que verificar todas as sequências possíveis de palavras contra todas as possíveis sequências de palavras em outras linhas, o que é extremamente complicado e não será reproduzido aqui.