Search code examples
perlbackspaceoutput-formatting

Update command line output


My program (which happens to be in Perl, though I don't think this question is Perl-specific) outputs status messages at one point in the program of the form Progress: x/yy where x and yy are a number, like: Progress: 4/38.

I'd like to "overwrite" the previous output when a new status message is printed so I don't fill the screen with status messages. So far, I've tried this:

my $progressString = "Progress\t$counter / " . $total . "\n";
print $progressString;
#do lots of processing, update $counter
my $i = 0;
while ($i < length($progressString)) {
    print "\b";
    ++$i;
}

The backspace character won't print if I include a newline in $progressString. If I leave out the newline, however, the output buffer is never flushed and nothing prints.

What's a good solution for this?


Solution

  • Use autoflush with STDOUT:

    local $| = 1; # Or use IO::Handle; STDOUT->autoflush;
    
    print 'Progress: ';
    my $progressString;
    while ...
    {
      # remove prev progress
      print "\b" x length($progressString) if defined $progressString;
      # do lots of processing, update $counter
      $progressString = "$counter / $total"; # No more newline
      print $progressString; # Will print, because auto-flush is on
      # end of processing
    }
    print "\n"; # Don't forget the trailing newline