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

Hi, I want to write logs from my perl script to the same line in stdout instead of scrolling endlessly. Sort of a progress meter. I tried to do

print STDOUT $message;
seek STDOUT, 0-length($message), 2;

But that didn't work. Any ideas?
Atli.

Replies are listed 'Best First'.
Re: Writing to same line in STDOUT
by grinder (Bishop) on Jun 14, 2001 at 13:28 UTC

    Nice try! Instead, try printing "\r" to bring the cursor back to the beginning of the line. That way you can overwrite the same line to your heart's content.

    #! /usr/bin/perl use strict; my $in = shift || '/usr/dict/words'; open IN, $in or die "Cannot open $in for input: $!\n"; while( <IN> ) { chomp; print "$_\r"; } close IN; print "\n";


    --
    g r i n d e r

      ...but you'd better make sure that you're actually writing to a terminal:

      #!/usr/bin/perl use strict; my $in = shift || '/usr/share/dict/words'; my $running_on_terminal = -t STDOUT; my $last_word_length; open IN, $in or die "Cannot open $in for input: $!\n"; while( <IN> ) { chomp; if ($running_on_terminal) { my $length_diff = $last_word_length - length($_); $length_diff >= 0 or $length_diff = 0; print ("\rProcessing $_..." . (" " x $length_diff) . ("\b" x $length_diff)); $last_word_length = length($_); } # do something with $_ } print "\n" if ($running_on_terminal); close IN;

      caveat: this code still assumes the user's terminal is wide enough for any line we're going to print.

      You might want to wrap it up into a module or object, so you can go:

      my $pm = new ProgressMeter(-items => scalar @list); $pm->start; my $c; for my $item (@list) { $pm->update(++$c); } $pm->finish;

      I wrote something like that once, but unfortunately it is owned by the company I wrote it for :-(