最近、それぞれ約 6 ギガバイトのいくつかのログ ファイルを解析する必要がありました。STDIN を配列に割り当てると、Perl は喜んで 6 ギガバイトをメモリに読み込もうとするため、バッファリングが問題でした。私は次の回避策を思いつきました。ファイルを 1 行ずつ読み取るだけで、大量のメモリのブラックホール バッファリングの渦を回避できます。そうしないと、すべてのシステム リソースが奪われてしまいます。
注: このスクリプトが行うのは、6 ギガバイトのファイルをいくつかの小さなファイルに分割することだけです (サイズは、各出力ファイルに含まれる行数によって決まります)。興味深い点は、while ループと、ログ ファイルから変数への 1 行の割り当てです。ループは、ファイル全体を反復して 1 行を読み取り、それに対して何かを実行してから繰り返します。結果、大規模なバッファリングはありません...実際の例を示すためだけに、スクリプト全体をそのまま残しました...
#!/usr/bin/perl -w
BEGIN{$ENV{'POSIXLY_CORRECT'} = 1;}
use v5.14;
use Getopt::Long qw(:config no_ignore_case);
my $input = '';
my $output = '';
my $lines = 0;
GetOptions('i=s' => \$input, 'o=s' => \$output, 'l=i' => \$lines);
open FI, '<', $input;
my $count = 0;
my $count_file = 1;
while($count < $lines){
my $line = <FI>; #assign a single line of input to a variable
last unless defined($line);
open FO, '>>', "$output\_$count_file\.log";
print FO $line;
$count++;
if($count == $lines){
$count=0;
$count_file++;
}
}
print " done\n";
スクリプトは、次のようにコマンド ラインで呼び出されます。
(スクリプト名) -i (入力ファイル) -o (出力ファイル) -l (出力ファイルのサイズ(行数))
探しているものとまったく同じでなくても、いくつかのアイデアが得られることを願っています。:)