複数の大容量ファイルからチャンクをマージする必要があります。各行にはファイル名とバイトオフセットが含まれます。
# file begin end
foo/a 11970 12010
foo/a 22995 23035
foo/b 45090 45130
foo/b 46035 46075
foo/b 48150 48190
foo/c 16200 16240
foo/c 17550 17590
foo/c 18540 18580
foo/c 26730 26770
foo/c 34245 34285
tail -c
とを使用して抽出を実行できますが、head -c
これにより同じファイルが複数回再開されるため、プロセスが遅くなります。私が思いついたユニークな解決策は、各ブロックの先頭を見つけて最後まで印刷し、各ファイルを一度だけ開くプログラムを書くことです。
コメントありますか?
ベストアンサー1
Perlはこのように動作するはずです。適切な場合は、ファイル名を変更してください。
#!/usr/bin/env perl
use strict;
use warnings;
use IO::Handle;
open(my $list_fh, '<', 'somefile') or die "Failed to open list file: $!";
open(my $out_fh, '>', 'outfile') or die "Failed to open out file: $!";
my $merge_fh = IO::Handle->new();
my $cur_fname = q{};
my $buff;
while ( my $line = <$list_fh> ) {
next if $line =~ /^\s?#/;
chomp($line);
my ($fname, $begin, $end) = split(/\s+/, $line);
if ( $cur_fname ne $fname ) {
$merge_fh->close() if $merge_fh->opened();
open($merge_fh, '<', $fname) or die "Failed to open file: $!";
$cur_fname = $fname;
}
seek($merge_fh, $begin, 0);
read($merge_fh, $buff, $end - $begin);
print {$out_fh} $buff or die "Failed to write to $cur_fname: $!";
}
$merge_fh->close();
$out_fh->close();
$list_fh->close();