См. perlrun
.
Когда был активирован переключатель -i
, perl запускает программу, используя ARGVOUT
в качестве дескриптора файла по умолчанию вместо STDOUT
.Если имеется несколько входных файлов, то каждый раз, когда операция <>
или <ARGV>
или readline(ARGV)
завершается с одним из входных файлов, он закрывает ARGVOUT
и снова открывает его для записи в следующее имя выходного файла.
Когда все входные данные из <>
исчерпаны (когда больше нет файлов для обработки), perl закрывает ARGVOUT
и восстанавливает STDOUT
как дескриптор файла по умолчанию снова.Или, как perlrun
говорит, что
#!/usr/bin/perl -pi.orig
s/foo/bar/;
эквивалентно
#!/usr/bin/perl
$extension = '.orig';
LINE: while (<>) {
if ($ARGV ne $oldargv) {
if ($extension !~ /\*/) {
$backup = $ARGV . $extension;
}
else {
($backup = $extension) =~ s/\*/$ARGV/g;
}
rename($ARGV, $backup);
open(ARGVOUT, ">$ARGV");
select(ARGVOUT);
$oldargv = $ARGV;
}
s/foo/bar/;
}
continue {
print; # this prints to original filename
}
select(STDOUT);
Как только вы говорите my @file = <>
и используете все входные данные, Perl закрывает дескриптор файла для файлов резервной копии и начинает направлениеснова выведите STDOUT
.
Обходной путь, я думаю, состоит в том, чтобы вызвать <>
в скалярном контексте и проверять eof(ARGV)
после каждой строки.Когда eof(ARGV)=1
, вы прочитали последнюю строку в этом файле, и у вас есть один шанс напечатать перед повторным вызовом <>
:
my @file = ();
while (<>) {
push @file, $_;
if (eof(ARGV)) {
# done reading current file
@processed_file = &do_something_with(@file);
# last chance to print before ARGVOUT gets reset
print @processed_file;
@file = ();
}
}