81

コマンドラインの前の行をどのように更新するのか、私はいつも疑問に思っていました。これの良い例は、Linux で wget コマンドを使用する場合です。次のような種類の ASCII 読み込みバーを作成します。

[======> ] 37%

もちろん、ローディングバーが移動し、パーセントが変化しますが、改行はしません。これを行う方法がわかりません。誰かが私を正しい方向に向けることができますか?

4

8 に答える 8

58

これを行う 1 つの方法は、現在の進行状況でテキスト行を繰り返し更新することです。例えば:

def status(percent):
    sys.stdout.write("%3d%%\r" % percent)
    sys.stdout.flush()

各行の最後に自動的に "\r\n" (キャリッジリターン改行) を出力するため、(これは Python です)sys.stdout.writeの代わりに使用したことに注意してください。カーソルを行頭に戻すキャリッジリターンが必要です。また、デフォルトでは改行の後 (またはバッファーがいっぱいになった後) にのみ出力をフラッシュするため、 が必要です。printprintflush()sys.stdout

于 2008-09-13T00:58:24.273 に答える
46

これを行うには、私が知っている2つの方法があります。

  • 行を消去するには、バックスペース エスケープ文字 ('\b') を使用します
  • curses選択したプログラミング言語にバインディングがある場合は、パッケージを使用してください。

また、Google はANSI Escape Codesを明らかにしました。これは良い方法のようです。参考までに、これを行う C++ の関数を次に示します。

void DrawProgressBar(int len, double percent) {
  cout << "\x1B[2K"; // Erase the entire current line.
  cout << "\x1B[0E"; // Move to the beginning of the current line.
  string progress;
  for (int i = 0; i < len; ++i) {
    if (i < static_cast<int>(len * percent)) {
      progress += "=";
    } else {
      progress += " ";
    }
  }
  cout << "[" << progress << "] " << (static_cast<int>(100 * percent)) << "%";
  flush(cout); // Required.
}
于 2008-09-13T00:56:00.240 に答える
4

以下は私の答えです。Cのコーディング、 Windows APIコンソール(Windows)を使用してください。

/*
* file: ProgressBarConsole.cpp
* description: a console progress bar Demo
* author: lijian <hustlijian@gmail.com>
* version: 1.0
* date: 2012-12-06
*/
#include <stdio.h>
#include <windows.h>

HANDLE hOut;
CONSOLE_SCREEN_BUFFER_INFO bInfo;
char charProgress[80] = 
    {"================================================================"};
char spaceProgress = ' ';

/*
* show a progress in the [row] line
* row start from 0 to the end
*/
int ProgressBar(char *task, int row, int progress)
{
    char str[100];
    int len, barLen,progressLen;
    COORD crStart, crCurr;
    GetConsoleScreenBufferInfo(hOut, &bInfo);
    crCurr = bInfo.dwCursorPosition; //the old position
    len = bInfo.dwMaximumWindowSize.X;
    barLen = len - 17;//minus the extra char
    progressLen = (int)((progress/100.0)*barLen);
    crStart.X = 0;
    crStart.Y = row;

    sprintf(str,"%-10s[%-.*s>%*c]%3d%%", task,progressLen,charProgress, barLen-progressLen,spaceProgress,50);
#if 0 //use stdand libary
    SetConsoleCursorPosition(hOut, crStart);
    printf("%s\n", str);
#else
    WriteConsoleOutputCharacter(hOut, str, len,crStart,NULL);
#endif
    SetConsoleCursorPosition(hOut, crCurr);
    return 0;
}
int main(int argc, char* argv[])
{
    int i;
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hOut, &bInfo);

    for (i=0;i<100;i++)
    {
        ProgressBar("test", 0, i);
        Sleep(50);
    }

    return 0;
}
于 2012-12-06T06:47:29.993 に答える
3

これがあなたの質問に対する答えです...(python)

def disp_status(timelapse, timeout):
  if timelapse and timeout:
     percent = 100 * (float(timelapse)/float(timeout))
     sys.stdout.write("progress : ["+"*"*int(percent)+" "*(100-int(percent-1))+"]"+str(percent)+" %")
     sys.stdout.flush()
     stdout.write("\r  \r")
于 2012-07-04T09:12:41.653 に答える
3

PowerShell には、スクリプトの実行時に更新および変更できるコンソール内の進行状況バーを作成する Write-Progress コマンドレットがあります。

于 2008-09-13T01:10:54.027 に答える
2

Greg's answer のフォローアップとして、複数行のメッセージを表示できる彼の機能の拡張バージョンを次に示します。表示/更新したい文字列のリストまたはタプルを渡すだけです。

def status(msgs):
    assert isinstance(msgs, (list, tuple))

    sys.stdout.write(''.join(msg + '\n' for msg in msgs[:-1]) + msgs[-1] + ('\x1b[A' * (len(msgs) - 1)) + '\r')
    sys.stdout.flush()

注: 私は Linux 端末を使用してこれをテストしただけなので、Windows ベースのシステムでは走行距離が異なる場合があります。

于 2012-06-23T22:44:09.563 に答える
0

スクリプト言語を使用している場合は、「tput cup」コマンドを使用してこれを行うことができます... PS これは私の知る限り Linux/Unix のものです...

于 2009-10-24T18:55:46.087 に答える