binmode(стандартный вывод, «:utf8»); и окончания строк Unix в Strawberry perl

#perl #newline

#perl #перевод строки

Вопрос:

С Strawberry perl v5.28.1 в Windows 10 я пытаюсь добиться того же результата, что и в Linux, а именно получить файл в кодировке UTF8 с окончаниями строк Unix.

Вот мой сценарий на Perl:

 #!perl -w

use strict;
use utf8;
use Encode qw(encode_utf8);
use Digest::MD5 qw(md5_hex);

binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");

my %words;

while(<>) {
        # change yo to ye
        tr/ёЁ/еЕ/;

        # extract russian word and its optional explanation
        next unless /^([А-Я]{2,})|?([А-Я ,-]*)/i;
        my ($word, $expl) = (uc $1, $2);

        if (length($word) <= 3) {
                print $word;
                # if explanation is missing, omit the pipe
                print (length($expl) > 3 ? "|$explx0A" : "x0A");
        } else {
                # print the md5 hash and omit the pipe and explanation
                print md5_hex(encode_utf8('my secret' . $word)) . "x0A";
        }
}
 

Вот мой входной файл:

 ААК|Плоскодонное речное судно
ААРОНОВЕЦ|
ААРОНОВЩИНА|
ААТ|Драгоценный красный камень в Японии
АБА|Толстое и редкое белое сукно
АБАЖУР|
АБАЖУРОДЕРЖАТЕЛЬ|
АБАЗ|Грузинская серебряная монета
АБАЗА|
 

Вот как я его запускаю (я использую type вместо < , потому что у меня есть множество входных файлов в моем реальном варианте использования):

 type input.txt | perl encode-words-ru.pl > output.txt
 

Независимо от того, что я пытаюсь использовать в приведенном выше исходном коде Perl, строки в output.txt завершаются x0Dx0A

Пожалуйста, помогите мне остановить perl от «помощи» мне!

Комментарии:

1. Из документации perlio: Если вам нужны окончания строк UNIX на платформе, которая обычно выполняет перевод CRLF, но все еще хочет использовать UTF-8 или кодировку по умолчанию, уместно добавить :perlio в переменную среды PERLIO. Вероятно, стоит изучить этот подход.

2. Вы также должны использовать :encoding(UTF-8) , а не :utf8 , кстати

3. К сожалению, оба ваших предложения не помогли: @SET PERLIO='perlio' и binmode(STDOUT, ":encoding(UTF-8)");

4. В нем говорится, что использовать :perlio нельзя perlio . Двоеточия важны. (В данный момент у меня нет доступа к компьютеру с Windows для собственного тестирования).

5. И документация, на которую я ссылался, объясняет, почему :encoding(UTF-8) это предпочтительнее (хотя в большинстве примеров это не используется, вздох).

Ответ №1:

Вероятно, есть лучший способ, но вы могли бы создать STDOUT дескриптор :raw файла, а затем самостоятельно закодировать вывод.

 binmode STDOUT;    # or  binmode STDOUT, ":raw";
...
print (length($expl) > 3 ? encode_utf8("|$expln") : "n");   # $exp1 is already decoded
...
print md5_hex(encode_utf8('my secret' . $word)) . "n";