Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

How to UPDATE rather than append to STDOUT?

by Anonymous Monk
on Jun 05, 2002 at 09:29 UTC ( [id://171771]=perlquestion: print w/replies, xml ) Need Help??

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

Perlmonks?

Does anyone know of a way I can REPLACE a counter in STDOUT rather than append new lines to the display.

If I knew what this was called I'd search for it :)

I want to put a counter on a status line but rather than have to drop a new line for each increment eg:
1
2
3

I'd prefer to have the counter update on the same line ie.3 replaced by 4 replaced by 5 etc?? So I don't have the display scrolling over screens and screens of text!

Is there a way to do this using standard Perl tools?

Any help is MUCH, MUCH appreciated.

Replies are listed 'Best First'.
Re: How to UPDATE rather than append to STDOUT?
by Dog and Pony (Priest) on Jun 05, 2002 at 09:50 UTC
    As some people have said, \b works for this, but so does \r:
    > perl -e "for(1..10){print qq(\r$_.);select undef,undef,undef,0.5}"
    Just thought I'd mention it. It depends on exactly what you want done, and if it is anything complex, have a look at suggested modules instead. :)
    You have moved into a dark place.
    It is pitch black. You are likely to be eaten by a grue.
Re: How to UPDATE rather than append to STDOUT?
by broquaint (Abbot) on Jun 05, 2002 at 09:39 UTC
    Short of using the various terminal manipulation tools you could use the funky backspace character \b
    $|++; print " "; for (0..20) { select undef, undef, undef, 0.25; print "\b\b"; printf "%2d", $_; } print "\n";
    That isn't the greatest example but I'm sure you get the picture ;-)
    HTH

    _________
    broquaint

Re: How to UPDATE rather than append to STDOUT?
by marvell (Pilgrim) on Jun 05, 2002 at 09:45 UTC

    You're not actually going to update the contents of STDOUT, you're going to exploit your terminal in order to move the cursor around.

    You could look at Term::* and Curses::*. There, you will find a vast array of terminal manipulation routines.

    You could use the backspace character (\b), as someone just mentioned.

    Update: or carriage return (\r)

    --
    ¤ Steve Marvell

Re: How to UPDATE rather than append to STDOUT?
by maverick (Curate) on Jun 05, 2002 at 15:09 UTC
    On any of the various Un*x you can use this code. This may work on windows as well (dunno, I don't use it)
    $|++; for ($i=0; $i<1000; $i++) { print "\r$i"; } print "\n";
    The first line turns off buffering, I suspect you want to see the numbers increment exactly as they happen.

    Use "\r" to send the cursor back to the beginning of the line. If you use \b to backspace one character, you'd have to keep up with how long $i has become, and/or add/remove \b's if you change the text of your status line. Send the cursor to the front of the line, reprint the whole thing and be done with it.

    Print a \n at the bottom of the loop. Otherwise your terminal prompt (or the next line of output) will get displayed at the end of the last status line and just look plain weird (especially if it starts with a number :) ).

    HTH

    /\/\averick
    OmG! They killed tilly! You *bleep*!!

Re: How to UPDATE rather than append to STDOUT?
by greenFox (Vicar) on Jun 05, 2002 at 12:45 UTC

    As well as the other methods suggested in this thread you can also (if you are on a unix box at least) use "tput" to move the cursor around.

    system("tput cup 4 10");

    will move the cursor to position 4,10 (top left is 0,0 so we are down 4 and across 10). Probably a bit of an overkill where \b might do :)

    --
    my $chainsaw = 'Perl';

Re: How to UPDATE rather than append to STDOUT?
by Anonymous Monk on Jun 05, 2002 at 09:59 UTC

    You could try using backspaces to back up over the previous number and overwrite it. Or use the ANSI cursor escape sequences to move back to the start of the line or directly to the position on the line and overwrite.

    The following code is good Perl, but it does work.

    #!e:\perl\bin\perl.exe -w use strict; use warnings; use diagnostics; for( my $n=1; $n<1000; $n++) { my $back = length $n; print $n, substr "\b\b\b\b", 0, $back; }
Re: How to UPDATE rather than append to STDOUT?
by particle (Vicar) on Jun 18, 2002 at 12:05 UTC
    this wasn't mentioned, so i thought i'd add it: you can use $. (input record number) to track which record you've reading from a file.

    perl -ne "print qq/\r$. lines processed/;select undef, undef, undef, 0 +.2" your_file_here
    four argument select is used as a sub-second delay (sleep allows only integer seconds,) to emulate file processing.

    ~Particle *accelerates*

      You can call a system("clear") before each print statement.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://171771]
Approved by schumi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2024-03-19 04:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found