Я предполагаю, что вы хотите снова открыть STDOUT, чтобы заставить работать функцию write
.Однако правильным решением для этого является либо указание дескриптора файла, либо в меньшей степени использование select
.
write FILEHANDLE;
или
select FILEHANDLE;
write;
К сожалению, кажется, что IO perlform немного загадочен и, похоже, не учитывает лексические дескрипторы файлов.
Ваша проблема в том, что вы не можете повторно использовать форматированный текст в программе, поэтому требуется немного триси-программирования.Что вы можете сделать, это открыть дескриптор файла, который печатает в скаляр.Это еще одна загадочная функциональность Perl, но в этом случае, возможно, это единственный способ сделать это напрямую.
# Using FOO as format to avoid destroying STDOUT
format FOO =
VARIABLE @<<<<<< @<<<<<< @<<<<<<
$x $y $z
.
my $foo;
use autodie; # save yourself some typing
open INPUT, '<', "text.txt"; # normally, we would add "or die $!" on these
open FOO, '>', \$foo; # but now autodie handles that for us
open my $output, '>', "output.txt";
while (<FILE>) {
$foo = ""; # we need to reset $foo each iteration
write FOO; # write to the file handle instead
print $output $foo; # this now prints $foo to output.txt
do_something($foo); # now you can also process the text at the same time
}
Как вы заметите, теперь мы сначала печатаем отформатированную строку в скаляр $foo
.Пока он есть, мы можем обрабатывать его как обычные данные, поэтому нет необходимости сохранять его в файл и повторно открывать его, чтобы получить данные.
На каждой итерации данные объединяются до конца $foo
, чтобы избежать накопления, нам нужно сбросить $foo
. лучший способ справиться с этим - сделать $foo
лексическим внутри области действия, но, к сожалению, нам нужно объявить $foo
вне цикла while, чтобы иметь возможность использовать его в open
Statement.
Возможно, возможно использовать local $foo
внутри цикла while, но я думаю, что это добавляет еще больше плохой практики к этому и без того очень плохому хаку.1034 * Вывод:
Учитывая все сказанное и сделанное, я подозреваю, что лучший способ справиться с этим - вообще не использовать perlform и каким-либо другим способом форматировать данные.Хотя perlform может хорошо подходить для печати в файл, он не подходит для того, что вы имеете в виду.Я помню этот вопрос из более раннего, возможно, был какой-то другой ответ, который будет работать лучше.Например, sprintf
, например Джонатан предложил