$str != '`'
- числовое сравнение.И "0\n"
, и "`"
(а также любая строка, не начинающаяся с десятичной цифры или точки) имеют числовой ноль, поэтому они равны.
Вы предполагали использовать сравнение строк ne
.
(Кроме того, всегда use strict;
и use warnings;
; последний мог бы поймать эту ошибку.)
Более типичный способ написать это было бы
while (my $str = <>) {
last if $str =~ /^`$/;
$str =~ tr/!-~/P-~!-O/;
print $str;
}