Как я могу напечатать только Unix Newline в Perl на Win32? - PullRequest
11 голосов
/ 30 ноября 2009

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

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

Спасибо!

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

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

use strict;
use warnings;

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

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

  }
  print;
}

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

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

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

Ответы [ 5 ]

12 голосов
/ 30 ноября 2009

При печати "\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 ).

4 голосов
/ 30 ноября 2009

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

1 голос
/ 01 декабря 2009

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

use open OUT => ':raw';

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

0 голосов
/ 30 ноября 2009

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

while (<>) {
    binmode;
    chomp;        # strip off \r\n
    while (s/search/replace/) {
        # ...
    }
    print;
    print "\n";   # add your own line ending back
}
0 голосов
/ 30 ноября 2009

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

print "\012";

...