Aqui está um pequeno script em perl para fazer isso. Ele lê todo o arquivo na memória, portanto pode não ser apropriado para arquivos realmente grandes.
perl -0777 -snE '
@lines = split /\n/;
for $idx (grep {$lines[$_] =~ $p} 0...$#lines) {
say join "\n", @lines[$idx-($n-1) .. $idx+($n-1)], "--";
}
' -- -n=3 -p='X' file