Как я могу напечатать только новую строку unix в Perl на Win32?

По умолчанию perl печатает \r\n в среде win32. Как я могу переопределить это? Я использую perl, чтобы внести некоторые изменения в некоторый исходный код в репозиторий, и я не хочу менять все символы новой строки.

Я попытался изменить разделитель выходной записи, но не повезло.

Спасибо!

Изменить: Требуется включить образец кода - я выполняю поиск и заменю на некоторые файлы, которые следуют относительно прямолинейному шаблону, например:

#!/usr/bin/perl
# test.pl

use strict;
use warnings;

$/ = undef;
$\ = "\n"; 
$^I=".old~";

while (<>) {
  while (s/hello/world/) {

  }
  print;
}

Это должно заменить любые случаи "привет" на "мир" для любых файлов, переданных в строке cmd.

Изменить 2: Я попробовал binmode, как было предложено, без какой-либо удачи. Я немного поразмыслил и обнаружил, что $^I (специальная переменная inplace edit) переопределяет binmode. Любая работа вокруг, чтобы все еще иметь возможность использовать редактирование inplace?

Изменить 3: Как указывает Синан, мне нужно использовать binmode ARGVOUT с $^I вместо binmode STDOUT в моем примере. Спасибо.

Ответ 1

Печать "\n" в дескриптор файла в Windows по умолчанию генерирует символ CARRIAGE RETURN ("\015"), за которым следует символ LINE FEED ("\012"), поскольку эта стандартная последовательность строк в Windows.

Это происходит прозрачно, поэтому вам нужно переопределить его для специального дескриптора файла ARGVOUT (см. perldoc perlvar):

#!/usr/bin/perl -i.bak

use strict; use warnings;

local ($\, $/);

while (<>) {
    binmode ARGVOUT;
    print;
}

Вывод:

C:\Temp> xxd test.txt
0000000: 7465 7374 0d0a 0d0a                      test....

C:\Temp> h test.txt

C:\Temp> xxd test.txt
0000000: 7465 7374 0a0a                           test..

См. также perldoc open, perldoc binmode и perldoc perliol (спасибо daotoad).

Ответ 2

Работает ли binmode( STDOUT )?

Ответ 3

Re: ваш вопрос о том, что binmode теряется, когда $^I открывает новый дескриптор вывода, вы можете решить это с помощью open прагма:

use open OUT => ':raw';

который заставит все дескрипторы файлов, открытые для записи, иметь для этого кэш-слой ': raw' PerlIO (эквивалентный binmode без аргумента). Просто позаботьтесь, если вы открываете что-либо еще для вывода, который вы применяете :crlf или любого другого слоя по мере необходимости.

Ответ 4

Unix newline - это символ LINEFEED, который является кодом ASCII 10.

print "\012";

Ответ 5

Данные, которые вы читаете, содержат концы строк, поэтому вы снова получаете их обратно. Вы можете отключить их с помощью chomp, а затем добавить свой собственный конец назад, если вы установили binmode, как описывает Sinan::

while (<>) {
    binmode;
    chomp;        # strip off \r\n
    while (s/search/replace/) {
        # ...
    }
    print;
    print "\n";   # add your own line ending back
}