Как я могу напечатать только новую строку 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
}