sub read_block { my ($fh) = @_; my $header = <$fh>; return undef if !defined($header); my @block = $header; do { my $line = <$fh>; die "Unexpected end of file\n" if !defined($line); chomp($line); push @block, $line; while ($line !~ /footer/); return \@block; } while (my $block = read_block($fh)) { ...process block... }