如何使用 Go 将格式化字符串打印到 stdout 中的同一行?

sgm*_*sgm 6 string macos stdout go

我正在迭代一个数组并将每个数组元素的格式化字符串打印到终端(stdout)。我不想在新行上打印每个元素,而是想用程序的最新输出覆盖以前的输出。

我正在使用 macOS。

我尝试了几种方法:

// 'f' is the current element of the array
b := bytes.NewBufferString("")
if err != nil {
    fmt.Printf("\rCould not retrieve file info for %s\n", f)
    b.Reset()
} else {
    fmt.Printf("\rRetrieved %s\n", f)
    b.Reset()
}
Run Code Online (Sandbox Code Playgroud)

第二种方法是\r从字符串中删除并在每个输出之前添加附加 Printf:fmt.Printf("\033[0;0H")

Jac*_*cik 11

您可以使用ANSI 转义码

首先,使用 保存光标位置fmt.Print("\033[s"),然后对于每一行,恢复位置并在打印该行之前清除该行fmt.Print("\033[u\033[K")

您的代码可能是:

// before entering the loop
fmt.Print("\033[s") // save the cursor position

for ... {
    ...
    fmt.Print("\033[u\033[K") // restore the cursor position and clear the line
    if err != nil {
        fmt.Printf("Could not retrieve file info for %s\n", f)
    } else {
        fmt.Printf("Retrieved %s\n", f)
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

除非您的程序打印屏幕底部的行,从而生成文本滚动,否则它应该可以工作。在这种情况下,您应该删除\n并确保没有线条超过屏幕(或窗口)宽度。

另一种选择是在每次写入后将光标向上移动:

for ... {
    ...
    fmt.Print("\033[G\033[K") // move the cursor left and clear the line
    if err != nil {
        fmt.Printf("Could not retrieve file info for %s\n", f)
    } else {
        fmt.Printf("Retrieved %s\n", f)
    }
    fmt.Print("\033[A") // move the cursor up
    ...
}
Run Code Online (Sandbox Code Playgroud)

同样,只要您的线条适合屏幕/窗口宽度,此操作就有效。