Perl:Unget to<>

时间:2013-10-14 09:04:42

标签: perl filehandle

我想从<>中读取100 KB,对其进行一些测试,然后将100 KB恢复,这样它们将被<>读取后面。

在元代码中:

$data100kb = read(<>,100000);
testing($data100kb);
unget(<>,$data100kb);
while(<>) {
  do stuff;
}

我事先并不知道&lt;&gt;将为我提供实际文件,管道或实际文件的串联。所以它应该适用于:

cat bigfile_a bigfile_b | perl my_program

假设bigfiles是1000 * RAM大小,因此复制输入非常昂贵。

如果我只能从STDIN读取,那是可以接受的。

背景

第一个100kb告诉我如何解析完整输入,但解析器也需要这个输入。

3 个答案:

答案 0 :(得分:1)

这似乎适用于STDIN。如果可以更快地完成它将会很棒。

read(STDIN, $first, 100000);
unget($first);

compute($first);

while($_=get_line()) {
    # Similar to while(<>)
}

my @line_cache;
sub get_line {
    if(@line_cache) {
        my $line = shift @line_cache;
        if(@line_cache) {
            # not last line                                                                                                            
            return $line;
        } else {
            # last line - may be incomplete                                                                                            
            if(substr($line, -1, 1) eq $/) {
                # Line is complete                                                                                                     
                return $line;
            } else {
                return $line. scalar(<STDIN>);
            }
        }
    } else {
        return scalar(<STDIN>);
    }
}

sub unget {
    for(@_) {
        # Split into lines                                                                                                             
        push @line_cache, split m:(?<=$/):;
    }
}

答案 1 :(得分:1)

为后代...我写了FileHandle :: Unget解决这个问题。

答案 2 :(得分:0)

我不知道这是否满足您的需要。如果您坚持使用&lt;&gt ;,那么我猜您必须使用tie

#copy STDIN to another filehandle: $fh
my $fakefile = join '', <STDIN>;
open my $fh, '<', \$fakefile;

#read 100kb
read $fh, my $data100kb, 100_000;

#do something with the data
#$data100kb =~ y/a/b/;
#print $data100kb;

#reset $fh
seek $fh, 0, 0;

while(<$fh>){
    print;# do some stuff
}