STDOUT到数组Perl

时间:2012-01-11 07:01:24

标签: perl stdout

我正在编译Perl程序,我正在将输出STDOUT写入文件。在同一个程序中,我想在STDOUT的输出上使用while函数运行另一个小脚本。所以,我需要将第一个脚本的输出保存在一个数组中,然后我可以在< @ 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循环中使用,或者如何在while循环中直接使用STDOUT。我必须确保第一部分完全执行。提前谢谢。

3 个答案:

答案 0 :(得分:6)

由于您重新映射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工作的检查,输入文件完成后的closeuse strict;use warnings;的使用。 (我只和Perl合作了20年,我知道我不相信我的脚本,直到他们用这些设置运行干净。)

答案 1 :(得分:0)

假设第一个程序的输出是制表符分隔的:

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

答案 2 :(得分:0)

我假设您要重新打开STDOUT以使write功能正常工作。但是,正确的解决方案是指定文件句柄,或者在较小程度上使用select

write FILEHANDLE;

select FILEHANDLE;
write;

不幸的是,似乎perlform的IO有点神秘,似乎不允许词法文件句柄。

您的问题是您无法在程序中重复使用格式化文本,因此需要进行一些三重编程。你可以做的是打开一个打印到标量的文件句柄。这是另一种有点神秘的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词汇,但不幸的是我们需要在while循环之外声明$foo以便能够使用它在open声明中。

可能可以在while循环中使用local $foo,但我认为这会给这个已经非常糟糕的黑客添加更多不好的做法。

<强>结论:

完成上述所有操作后,我怀疑处理此问题的最佳方法是根本不使用perlform,并以其他方式格式化数据。虽然perlform可能非常适合打印到文件,但它并不是最适合您的想法。我从前面回忆起这个问题,也许还有一些其他答案会更好。例如使用sprintf,例如Jonathan suggested