Search code examples
perlforeachperl-moduleprogressbuffering

print doesn't work while iterations are going inside foreach loop


I try to find a way to print a progressbar on the commandline while parsing logfiles. Get logfiles=> foreach file => foreach line {do}.

The idea: I want to print a part of the progressbar in every "foreach file" loop. Meaing: print the whole bar if you just parse 1 file. print half of the bar for every file when u parse 2 files and so on. You find the specific code at the bottom.

The problem: The output (print "*") is printed after ALL foreach iteration are done - not in between. Details are in the Code.

Does someone have an idea how to print inside a foreach? Or can tell me the problem? I don't get it :(.

my @logfiles=glob($logpath);

print "<------------------>\n";
$vari=20/(scalar @logfiles);

foreach my $logfile (@logfiles){
    open(LOGFILEhandle, $logfile);
    @lines = <LOGFILEhandle>;

    print "*" x $vari;   #won't work, only after loop. Even a "print "*";" doesn't work

    foreach my $line (@lines){
        #print "*"; works "in between". print "*" x $vari; does not.

        if ($line=~/xyz/){
            ......
            ......
        }
    close(LOGFILEhandle);
    }
}

Solution

  • You are suffering from buffering. The output is buffered until a certain amount is reached or you print a newline. To change this behaviour simply add

    $| = 1 ;
    

    at the top of your file. This will turn on autoflush for STDOUT. There is more than one way to do it and a little bit longer and less cryptic is Borodins suggestion:

    STDOUT->autoflush();