Command line 如何设置命令行的动画?

Command line 如何设置命令行的动画?,command-line,Command Line,我一直想知道人们是如何更新命令行中的前一行的。在linux中使用wget命令就是一个很好的例子。它会创建一个ASCII加载条,其排序如下: [=======>]37% 当然,加载条会移动,百分比也会改变,但不会产生新行。我不知道怎么做。有人能给我指出正确的方向吗?我知道有两种方法可以做到这一点: void DrawProgressBar(int len, double percent) { cout << "\x1B[2K"; // Erase the entire curren

我一直想知道人们是如何更新命令行中的前一行的。在linux中使用wget命令就是一个很好的例子。它会创建一个ASCII加载条,其排序如下:

[=======>]37%


当然,加载条会移动,百分比也会改变,但不会产生新行。我不知道怎么做。有人能给我指出正确的方向吗?

我知道有两种方法可以做到这一点:

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.
}
  • 使用退格转义字符('\b')删除行
  • 如果您选择的编程语言具有绑定,请使用
    curses
谷歌透露,这似乎是一个好办法。作为参考,这里有一个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.
}
void DrawProgressBar(整数长度,双百分比){

cout一种方法是根据当前进度重复更新文本行。例如:

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

请注意,我使用了
sys.stdout.write
而不是
print
(这是Python),因为
print
会在每一行的末尾自动打印“\r\n”(回车换行符新行)。我只需要回车符,它会将光标返回到行的开头。另外,
flush()
是必需的,因为默认情况下,
sys.stdout
仅在换行后(或缓冲区满后)刷新其输出。

PowerShell有一个Write-Progress cmdlet,可创建控制台内进度条,您可以在脚本运行时更新和修改该进度条。

如果您使用脚本语言,则可以使用“tput-cup”命令来完成此操作。。。 另外,据我所知,这是一个Linux/Unix的东西…

作为后续,这里是他的函数的扩展版本,允许您显示多行消息;只需传入要显示/刷新的字符串列表或元组

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的系统上,您的里程可能会有所不同。

以下是您问题的答案…(python)


下面是我的答案,使用windowsapi,编码为C

/*
* 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;
}
/*
*文件:ProgressBarConsole.cpp
*描述:控制台进度条演示
*作者:李健
*版本:1.0
*日期:2012-12-06
*/
#包括
#包括
处理hOut;
控制台\屏幕\缓冲区\信息bInfo;
char charProgress[80]=
{"================================================================"};
char spaceProgress='';
/*
*在[行]行中显示进度
*行从0开始到结束
*/
整数进度条(字符*任务,整数行,整数进度)
{
char-str[100];
内伦、巴伦、普洛斯伦;
协调crStart,crCurr;
GetConsoleScreenBufferInfo(hOut和bInfo);
crCurr=bInfo.dwCursorPosition;//旧位置
len=bInfo.dwMaximumWindowsSize.X;
barLen=len-17;//减去额外的字符
progressLen=(int)((progress/100.0)*barLen);
crStart.X=0;
crStart.Y=行;
sprintf(str,“%-10s[%-.*s>%*c]%3d%%”,任务,进度,charProgress,barlenprogresslen,spaceProgress,50);
#如果0//使用标准数据库
设置控制台位置(hOut、crStart);
printf(“%s\n”,str);
#否则
WriteConsoleOutputCharacter(hOut、str、len、crStart、NULL);
#恩迪夫
设置控制台位置(hOut,crCurr);
返回0;
}
int main(int argc,char*argv[])
{
int i;
hOut=GetStdHandle(标准输出句柄);
GetConsoleScreenBufferInfo(hOut和bInfo);

对于(i=0;i而言,秘诀是只打印行的和处的\r\n而不是\r\n或\r\n

\r称为回车,它将光标移动到行的开头

\n称为换行符,它将光标移动到下一行 在控制台中。如果只使用\r,则覆盖以前写入的行。 因此,首先写一行,如下所示:

[          ]
然后为每个勾号添加一个符号

\r[=         ]

\r[==        ]

...

\r[==========]
等等。 您可以使用10个字符,每个字符代表10%。 此外,如果要在完成时显示消息,请不要忘记添加足够的白色字符,以便覆盖以前写入的等号,如:

\r[done      ]

“c”中的printf和“\r”也是一样。@Nearoo通常会缓冲其输出,直到写入换行符(\n)。刷新会立即显示部分行。假设他在最新版本的Windows(ie 2000+)上运行Win32控制台应用程序(而不是DOS),ANSI转义码根本不起作用。正如您链接到的wikipedia文章中所述。如果在Windows上使用ANSI转义序列,您可以使用Ansicon。@naxa做Greg的回答(如上)是否为您工作?很可能是换行符有问题。请尝试将“\n”替换为“\r\n”。Greg可以工作,因此在一行上可以工作,但我尝试了多行消息更新。:)我已将脚本中的
\n
替换为
\r\n
,但仍然无法在windows上工作(您呢?)。我已获得
←[A]←[A
在一些消息之后,我怀疑
'\x1b[A'
序列没有执行
cmd.exe
@naxa the'\x1b中应该执行的操作[A'是游标向上的ANSI转义序列,用于将游标重置到我代码中行块的开头。我进一步研究了一下,发现了这一点。您可能希望在我的函数中添加一个if语句,以便在Windows上为stdout添加ANSI支持。定义了
bInfo
的位置在哪里?这完全有效。它非常有用在我看来,H也更简单。