更新命令行输出

发布于 2024-10-17 16:43:51 字数 569 浏览 1 评论 0原文

我的程序(恰好是用 Perl 编写的,尽管我不认为这个问题是 Perl 特有的)在程序中的某一点以 Progress: x/yy 形式输出状态消息,其中 xyy 是一个数字,例如:进度:4/38

我想在打印新的状态消息时“覆盖”以前的输出,这样我就不会用状态消息填充屏幕。到目前为止,我已经尝试过:

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;
}

如果我在 $progressString 中包含换行符,则不会打印退格字符。但是,如果我省略换行符,则输出缓冲区永远不会刷新并且不会打印任何内容。

对此有什么好的解决办法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一袭水袖舞倾城 2024-10-24 16:43:52

在程序早期的某处指定

$| = 1

打开输出缓冲区的自动刷新。

还可以考虑使用“\r”将光标移回行首,而不是尝试显式计算需要移回多少个空格。

就像你说的,在进度计数器运行时不要打印换行符,否则你将在单独的行上打印进度而不是覆盖旧行。

Say

$| = 1

somewhere early in your program to turn autoflushing on for the output buffer.

Also consider using "\r" to move the cursor back to the beginning of the line, rather than trying to explicitly count how many spaces you need to move back.

Like you said, don't print out a newline while your progress counter is running or else you will print out your progress on a separate line instead of overwriting the old line.

笨死的猪 2024-10-24 16:43:52

我知道这不完全是你所要求的,但可能更好。我遇到了同样的问题,所以没有太多地处理它,而是使用 Term::ProgressBar 看起来也不错。

I know it's not quite what you asked for, but possibly better. I happened on this same problem and so rather than deal with it too much went to using Term::ProgressBar which looks nice too.

是你 2024-10-24 16:43:52

我今天必须解决类似的问题。
如果您不介意重新打印整行,您可以执行以下操作:

print "\n";
while (...) {
     print "\rProgress: $counter / $total";
     # do processing work here
     $counter++;
}
print "\n";

“\r”字符是回车符 - 它将光标带回到行的开头。这样,您打印出的任何内容都会覆盖先前进度通知的文本。

I had to tackle something similar to this today.
If you don't mind reprinting the entire line, you could do something like this:

print "\n";
while (...) {
     print "\rProgress: $counter / $total";
     # do processing work here
     $counter++;
}
print "\n";

The "\r" character is a carriage return-- it brings the cursor back to the beginning of the line. That way, anything you print out overwrites the previous progress notification's text.

画骨成沙 2024-10-24 16:43:52

您还可以使用 ANSI 转义码直接控制光标。或者您可以使用 Term::ReadKey 来做同样的事情。

You can also use the ANSI escape codes to directly control the cursor. Or you can use Term::ReadKey to do the same thing.

筱武穆 2024-10-24 16:43:51

将自动刷新与 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文