명령줄에 애니메이션을 적용하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/60221

  •  09-06-2019
  •  | 
  •  

문제

나는 사람들이 명령줄에서 이전 줄을 어떻게 업데이트하는지 항상 궁금했습니다.이에 대한 좋은 예는 Linux에서 wget 명령을 사용할 때입니다.다음과 같은 종류의 ASCII 로딩 바를 생성합니다.

[======>                    ] 37%

물론 로딩 바가 이동하고 퍼센트가 변경되지만 새 줄이 만들어지지는 않습니다.이 작업을 수행하는 방법을 알 수 없습니다.누군가 나에게 올바른 방향을 알려줄 수 있습니까?

도움이 되었습니까?

해결책

내가 아는 두 가지 방법이 있습니다.

  • 줄을 지우려면 백스페이스 이스케이프 문자('\b')를 사용하세요.
  • 사용 curses 선택한 프로그래밍 언어에 바인딩이 있는 경우 패키지.

그리고 구글이 공개했다 ANSI 이스케이프 코드, 좋은 방법인 것 같습니다.참고로 이 작업을 수행하는 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.
}

다른 팁

이를 수행하는 한 가지 방법은 현재 진행 상황으로 텍스트 줄을 반복적으로 업데이트하는 것입니다.예를 들어:

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

제가 사용한 점 참고하세요 sys.stdout.write 대신에 print (이것은 Python입니다) 왜냐하면 print 각 줄의 끝에 자동으로 " "(캐리지 리턴 개행)을 인쇄합니다.커서를 줄의 시작 부분으로 되돌리는 캐리지 리턴을 원합니다.또한, flush() 기본적으로 sys.stdout 개행 이후(또는 버퍼가 가득 찬 이후)에만 출력을 플러시합니다.

비밀은 줄의 및 줄에 또는 대신 만 인쇄하는 것입니다.

은 캐리지 리턴이라고 하며 커서를 줄의 시작 부분으로 이동합니다.

n을 라인 피드라고하며 콘솔의 다음 줄에서 커서를 움직입니다. 만 사용하면 이전에 작성한 줄을 덮어쓰게 됩니다.따라서 먼저 다음과 같은 줄을 작성하십시오.

[          ]

그런 다음 각 틱에 대한 기호를 추가하십시오.

\r[=         ]

\r[==        ]

...

\r[==========]

등등.10개의 문자를 사용할 수 있으며 각 문자는 10%를 나타냅니다.또한 완료 시 메시지를 표시하려면 다음과 같이 이전에 작성한 등호를 덮어쓸 수 있도록 충분한 흰색 문자를 추가하는 것을 잊지 마십시오.

\r[done      ]

아래는 내 대답입니다. Windows API를 사용하세요.콘솔(Windows), 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;
}

PowerShell에는 스크립트가 실행될 때 업데이트하고 수정할 수 있는 콘솔 내 진행률 표시줄을 만드는 Write-Progress cmdlet이 있습니다.

귀하의 질문에 대한 답변은 다음과 같습니다...(파이썬)

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")

후속조치로 그렉의 답변, 여기에 여러 줄의 메시지를 표시할 수 있는 기능의 확장 버전이 있습니다.표시/새로 고침하려는 문자열의 목록이나 튜플을 전달하기만 하면 됩니다.

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 기반 시스템에서는 마일리지가 다를 수 있습니다.

스크립팅 언어를 사용하는 경우 "tput cup" 명령을 사용하여 이 작업을 수행할 수 있습니다.추신이것은 내가 아는 한 Linux/Unix에 관한 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top