Как объяснил @muru, браузеры не должны отправлять #foo на сервер. Они должны сами управлять фрагментами. Так что Apache вообще не должен его видеть.
Итак, эта проблема вовсе не проблема.
$ perl -lne '
s/_tr.*/_/;
unless (defined($prefixes) && m/^($prefixes)_/) {
$prefixes{$_}++;
$prefixes=join("|", map +( "\Q$_\E" ), keys %prefixes);
};
END { print join("\n", sort keys %prefixes) }' <(sort input.txt)
pj1_ex_24_i535_
pj3_ex_16_i535_
pj6_ex_14_i535_
pj6_ex_18_i535_
или даже короче, просто отслеживая последнюю увиденную строку, а не каждый уникальный префикс:
$ perl -lne '
next if (defined($last) && m/^\Q$last\E/);
s/_tr.*/_/;
$last=$_;
print' <(sort input.txt)
pj1_ex_24_i535_
pj3_ex_16_i535_
pj6_ex_14_i535_
pj6_ex_18_i535_
В обеих версиях \Q
и \E
в операции сопоставления m//
предотвращают интерпретацию любых метасимволов регулярного выражения -в $last
. например. если он содержит что-то вроде .*
, он будет интерпретироваться как литерал .
и литерал *
, а не как «ноль -или -больше любого символа».