Вот способ сделать это в Perl, не отсекая ничего, чтобы объем памяти программы не зависел от размеров обоих файлов (предполагается, что номера строк, которые будут напечатаны, отсортированы):
#!/usr/bin/perl
use strict; use warnings;
use autodie;
@ARGV == 2
or die "Supply src_file and filter_file as arguments\n";
my ($src_file, $filter_file) = @ARGV;
open my $src_h, '<', $src_file;
open my $filter_h, '<', $filter_file;
my $to_print = <$filter_h>;
while ( my $src_line = <$src_h> ) {
last unless defined $to_print;
if ( $. == $to_print ) {
print $src_line;
$to_print = <$filter_h>;
}
}
close $filter_h;
close $src_h;
Создать исходный файл:
C:\> perl -le "print for aa .. zz" > src
Создать файл фильтра:
C:\> perl -le "print for grep { rand > 0.75 } 1 .. 52" > filter
C:\> cat filter
4
6
10
12
13
19
23
24
28
44
49
50
Выход:
C:\> f src filter
ad
af
aj
al
am
as
aw
ax
bb
br
bw
bx
Чтобы работать с несортированным файлом фильтра, вы можете изменить цикл while
:
while ( my $src_line = <$src_h> ) {
last unless defined $to_print;
if ( $. > $to_print ) {
seek $src_h, 0, 0;
$. = 0;
}
if ( $. == $to_print ) {
print $src_line;
$to_print = <$filter_h>;
}
}
Это потратило бы много времени, если содержимое файла фильтра было довольно случайным, поскольку оно продолжало бы перематываться в начало исходного файла. В этом случае я бы рекомендовал использовать Tie :: File .