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

I've seen some perl scripts that output info to the terminal that seems to overwrite output it already had there. It doesn't use newlines or have wrapping text, it just prints overtop what was already there. Of course I never bothered to look at how these scripts did that and I'm sorry I didn't since I now need to do this. Can anyone point me in the right direction? Thanks.

Replies are listed 'Best First'.
Re: output on top of old output
by cog (Parson) on Mar 22, 2005 at 15:39 UTC
    You can use the "\r" char.

    #!/usr/bin/perl -w use strict; my $start = time; # let's see what time it is our $gap ||= 1; # how many seconds between prints while (1) { # and from now on local $| = 1; my $now = time; # see what time it is now my ( $sec, $min, $hour ) = ( $now - $start, 0, 0 ); # seconds passed while ( $sec > 3600 ) { $sec -= 3600; $hour++ } # hours while ( $sec > 60 ) { $sec -= 60 ; $min++ } # minutes printf ("\r%02d:%02d:%02d",$hour,$min,$sec); # print time sleep($gap); # wait a while }
Re: output on top of old output
by gellyfish (Monsignor) on Mar 22, 2005 at 15:25 UTC

    It probably positions the cursor using something like Curses or on of the Term::* modules if you are on a Unix-like system.

    /J\

Re: output on top of old output
by sh1tn (Priest) on Mar 22, 2005 at 15:28 UTC
    It's the "\b" char if that's the question:
    # UNIX style: perl -e '$|++;for(1..10){ print $_;sleep 1; print "\b"}' # dos style: perl -e "$|++;for(1..10){ print $_;sleep 1; print \"\b\"}"


      Except of course that doesn't work for output of more than one character - try printing 10 - 25 for instance. I guess you could change your "\b" to "\r" if all is required is to return to the beginning of the line.

      /J\

        What does "\r" do on a mac?
      This works fine for single digits, but if you increase the for loop to 15, the output gets all wonky:
      perl -e '$|++;for(1..15){ print $_;sleep 1; print "\b"} # prints: 1111115
      because, of course, you're only backspacing over one character. To avoid extra logic to figure out how many spaces to go back, you can just go to the beginning of the line with \r:
      perl -e '$|++;for(1..15){ print $_;sleep 1; print "\r"}

      Which one is "better" depends on your desired use, obviously.

      Addendum: Ooog, slow typing today.

        Basically, xorl, "\b" backs up one char, while "\r" rewinds the whole line :-)

        Remember, if you print a newline character, you won't be able to use these control characters to erase it.

        ... for(1..15){ print $_;sleep 1; print "\b"x(length$_)} ...


Re: output on top of old output
by xorl (Deacon) on Mar 22, 2005 at 16:35 UTC
    Thanks everyone the \r and \b were exactly what I needed!
Re: output on top of old output
by MrStretch (Sexton) on Mar 22, 2005 at 16:28 UTC
    If you are wanting to print multiple lines and then print over it all the next time, then your best bet is probly with the module term (i think) because it lets you clear the screen.