DEMO

ソースコード

以下のような CSI シーケンスを使って実装する. 今回は使用していないが, 行ではなくスクリーンを丸ごとクリアすることもできる.

詳しくはman console_codesを参照.

制御文字動作
\033[1Aカーソルを一行上に移動
\033[2K現在の行をクリア
\033[2Jスクリーンをクリア
\033[Hカーソルを左上(1,1)に移動
package main

import (
	"fmt"
	"time"
)

func main() {
	total := 50
	tick := 50 * time.Millisecond

	for i := 0; i <= total; i++ {
		fmt.Printf("now loading...\n")
		drawProgress(i, total)
		fmt.Printf("%d/%d\n", i, total)

		time.Sleep(tick)
		if i == total {
			fmt.Printf("finish\n")
			break
		}

		clearAboveNLines(3)
	}
}

func cursorUp() {
	fmt.Print("\033[1A")
}

// clear the whole line including '\n'
func clearLine() {
	fmt.Print("\033[2K")
}

func drawProgress(progress, total int) {
	fmt.Print("[")
	for j := 0; j < total; j++ {
		if j < progress {
			fmt.Print("#")
		} else {
			fmt.Print("-")
		}
	}
	fmt.Print("]\n")
}

func clearAboveNLines(n int) {
	for i := 0; i < n; i++ {
		clearLine()
		cursorUp()
	}
}