Recentemente ho avuto per analizzare diversi file di log che erano circa 6 gigabyte ciascuno. Il buffering era un problema dal momento che Perl avrebbe felicemente tentato di leggere quei 6 gigabyte in memoria quando assegnerei lo STDIN a un array ... Tuttavia, semplicemente non avevo le risorse di sistema disponibili per farlo. Ho trovato la seguente soluzione alternativa che legge semplicemente il file riga per riga e, quindi, evita l'enorme vortice di buffering della memoria blackhole che altrimenti richiederebbe tutte le risorse del mio sistema.
nota: tutto ciò che fa questo script è dividere quel file da 6 gigabyte in diversi più piccoli (la cui dimensione è dettata dal numero di righe da contenere in ogni file di output). Il bit interessante è il ciclo while e l'assegnazione di una singola riga dal file di registro alla variabile. Il ciclo eseguirà l'iterazione dell'intero file leggendo una singola riga, facendo qualcosa con esso e quindi ripetendo. Risultato, nessun enorme buffering ... Ho mantenuto intatto l'intero script solo per mostrare un esempio funzionante ...
#!/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";
script viene richiamato sulla linea di comando come:
(il nome dello script) -i (file di input) -o (file di output) -l (dimensione del file di output (cioè il numero di linee)
Anche se non è esattamente quello che stai cercando, spero che vi darà alcune idee :)
sei sicuro 'fff cat. | perl -e 'system ("./ 1.pl") "stampa il contenuto? per me solo 'cat fff | perl 1.pl' fa. – tuxuday