【问题标题】:Update command line output更新命令行输出
【发布时间】:2011-06-27 21:53:44
【问题描述】:

我的程序(恰好在 Perl 中,虽然我不认为这个问题是 Perl 特有的)在程序中的某个点输出状态消息,格式为 Progress: x/yy,其中 xyy 是一个数字,例如:Progress: 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 中包含换行符,则不会打印退格字符。但是,如果我省略换行符,则输出缓冲区永远不会被刷新,也不会打印任何内容。

有什么好的解决方案?

【问题讨论】:

    标签: perl backspace output-formatting


    【解决方案1】:

    您也可以使用ANSI escape codes 直接控制光标。或者你可以使用Term::ReadKey 来做同样的事情。

    【讨论】:

      【解决方案2】:

      我知道这并不完全符合您的要求,但可能更好。我也遇到了同样的问题,所以与其处理太多,不如使用Term::ProgressBar,这看起来也不错。

      【讨论】:

        【解决方案3】:

        我今天不得不处理类似的事情。 如果您不介意重新打印整行,您可以执行以下操作:

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

        “\r”字符是一个回车符——它将光标带回到行首。这样,您打印的任何内容都会覆盖之前的进度通知文本。

        【讨论】:

          【解决方案4】:

          对 STDOUT 使用 autoflush:

          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
          

          【讨论】:

          • 这类作品。我最终得到了相当乱码的输出,例如:5 / 73 / 70 / 7。在代码运行时,我看到“进度”一词和数字的各种乱码形式。
          • 我认为处理代码中的某些内容与标准输出有关。就其本身而言,您的代码有效。谢谢!
          【解决方案5】:

          $| = 1
          

          在程序早期的某个地方为输出缓冲区打开自动刷新。

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-07-13
            • 1970-01-01
            • 2021-01-14
            • 1970-01-01
            • 1970-01-01
            • 2021-08-26
            • 2020-09-08
            • 2013-01-05
            相关资源
            最近更新 更多