http://www.perlmonks.org?node_id=1040222

hyu968 has asked for the wisdom of the Perl Monks concerning the following question:

Perl Monks, Sorry if this is a trivial question but I am new to this environment and cannot figure out immediately how to do it. I am running a foreach loop for a huge number of elements (files). I need to track where I currently am, and therefore, I would like the program to spit out the current iteration of the loop. When I do it, it spits out the whole output at the end of execution. I am running active perl on Windows, and use Komodo Edit. Any help with this will be highly appreciated! Thanks, George
  • Comment on Dynamically printing out iteration number from foreach loop

Replies are listed 'Best First'.
Re: Dynamically printing out iteration number from foreach loop
by frozenwithjoy (Priest) on Jun 21, 2013 at 21:17 UTC

    This is happening because the output is being buffered. You can turn on the auto-flush for the buffer by adding the following somewhere in your script before what you want to be unbuffered:

    $| = 1;

    $| = 0; reverts everything back to normal. If you want to get more complicated, you can try IO::Handle, but it is probably overkill for what you need.

      You omitted the obligatory Suffering from Buffering.

      #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Awesome, thanks!
Re: Dynamically printing out iteration number from foreach loop
by zork42 (Monk) on Jun 23, 2013 at 16:02 UTC
    I need to track where I currently am, and therefore, I would like the program to spit out the current iteration of the loop.

    In Windows, "\r" can sometimes be useful when tracking the progress of a script. It's a bit like "\n", except "\n" moves to the left edge of the next line, whereas "\r" moves to the left edge of the current line.

    The following script prints 1 to 5 and a string on the same line of output.

    I normally put the "\r" at the start of the output. That way if the script dies or outputs something it will not overwrite the progress info. Also, if the output strings are of different sizes, you'll need to output some spaces at the end to overwrite the previous output string.

    ('Cmd' windows and their buffers can be made wider, if needed, by adjusting the "Screen Buffer Size" and "Window Size" in the "Layout" tab of the window's properties. Right-click on the window's title bar, then select "Properties".)
    use strict; use warnings; $| = 1; # enable auto-flush foreach my $i ( 1 .. 5 ) { my $output = '*' x (50 - 10*$i); print "\r$i : $output", " "x20; sleep 1; } print "\n";
    Output. NB Each line of output is printed on the same line of the 'Cmd' window.
    1 : **************************************** 2 : ****************************** 3 : ******************** 4 : ********** 5 :
      > In Windows, "\r" can sometimes be useful when tracking the progress of a script.

      why only in Windows? Carriage Return is a universal ASCII-code, no problems using it with Linux terminals or other OSes.¹ :)

      Cheers Rolf

      ( addicted to the Perl Programming Language)

      ¹) I'm sure someone will now come up with some esoteric OS (like TI99/4a home computer) which might have problems here ... =)