STDOUT для массива Perl - PullRequest
       8

STDOUT для массива Perl

2 голосов
/ 11 января 2012

Я компилирую программу на Perl, я записываю вывод STDOUT в файл.В этой же программе я хочу запустить другой небольшой скрипт, используя функцию while для вывода STDOUT.Итак, мне нужно сохранить выходные данные первого скрипта в массиве, затем я могу использовать в то время как <@array>.Как

open(File,"text.txt");
open(STDOUT,">output,txt");
@file_contents=<FILE>;

foreach (@file_contents){

//SCRIPT GOES HERE//

write;
}
format STDOUT =
VARIABLE    @<<<<<< @<<<<<<  @<<<<<<
             $x      $y       $z
.

//Here I want to use output of above program in while loop //

while(<>){

}

Как сохранить выходные данные первой программы в массиве, чтобы я мог использовать их в цикле while, или как я могу напрямую использовать STDOUT в цикле while.Я должен убедиться, что первая часть полностью выполнена.Заранее спасибо.

Ответы [ 3 ]

6 голосов
/ 11 января 2012

Поскольку вы переназначили STDOUT для записи в файл, вы, вероятно, можете закрыть STDOUT, а затем снова открыть файл для чтения.

То, куда вы собираетесь отправлять любые другие выходные данные, немноготайна, но, вероятно, вы можете решить это.Если бы это был я, я бы не стал возиться с STDOUT.Я бы сделал сценарий записи в дескриптор файла:

use strict;
use warnings;

open my $input, "<", "text.txt" or die "A horrible death";
open my $output, ">", "output.txt" or die "A horrible death";
my @file_contents = <$input>;
close($input);

foreach (@file_contents)
{
    # Script goes here
    print $output "Any information that goes to output\n";
}
close $output;

open my $reread, "<", "output.txt" or die "A horrible death";

while (<$reread>)
{
    # Process the previous output
}

Обратите внимание на использование лексических дескрипторов файла, проверку работоспособности open, close по окончании ввода файла,использование use strict; и use warnings;.(Я работаю с Perl уже 20 лет, и я знаю, что не доверяю своим сценариям, пока они не будут работать с этими настройками.)

0 голосов
/ 11 января 2012

Я предполагаю, что вы хотите снова открыть 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, например Джонатан предложил

0 голосов
/ 11 января 2012

Предполагается, что вывод вашей первой программы разделен табуляцией:

while (<>) {
    chomp $_;
    my ($variable, $x, $y, $z) = split("\t", $_);
    # do stuff with values
}     
...