コマンドライン出力の更新
-
14-11-2019 - |
質問
私のプログラム(これはPerlにありますが、この質問はPerl固有のものではないと思います)は、次の形式のプログラムのある時点でステータスメッセージを出力 Progress: x/yy
ここで x
と yy
のような数です: 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
.ただし、改行を省略すると、出力バッファがフラッシュされることはなく、何も出力されません。
これのための良い解決策は何ですか?
解決
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
他のヒント
言う
$| = 1
プログラムの初期のどこかで、出力バッファのオートフラッシュをオンにします。
また、戻る必要があるスペースの数を明示的にカウントするのではなく、" "を使用してカーソルを行の先頭に戻すことを検討してください。
あなたが言ったように、進行状況カウンタが実行されている間は改行を印刷しないでください。そうしないと、古い行を上書きするのではなく、別の行に進行状況を印刷します。
私はそれがあなたが求めたものではないことを知っていますが、おそらくより良いです。私はこの同じ問題で起こったので、それに対処するのではなく、あまりにも多くを使用して行きました Term::ProgressBar
それも素敵に見えます。
また、以下を使用することもできます ANSIエスケープコード カーソルを直接制御する。またはあなたが使うことができます 用語::ReadKey 同じことをする。
私は今日これに似た何かに取り組まなければなりませんでした。行全体を再印刷しても構わない場合は、次のようなことができます:
print "\n";
while (...) {
print "\rProgress: $counter / $total";
# do processing work here
$counter++;
}
print "\n";
" "文字はキャリッジリターンであり、カーソルを行の先頭に戻します。このようにして、印刷すると、以前の進行状況通知のテキストが上書きされます。