【问题标题】:How to print formatted string to the same line in stdout with Go?如何使用 Go 将格式化字符串打印到标准输出中的同一行?
【发布时间】:2019-05-12 21:56:13
【问题描述】:

我正在遍历一个数组并将每个数组元素的格式化字符串打印到终端(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()
}

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

【问题讨论】:

  • 如果从字符串末尾删除'\n'会发生什么?
  • 我删除了\n。奇怪的是,在某些行上,stdout 被覆盖了,但在大多数情况下它仍然无法正常工作。我还从字节包中删除了代码。似乎不再需要了。

标签: string macos go stdout


【解决方案1】:

您可以使用ANSI Escape Codes

首先用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)
    }
    ...
}

除非您的程序在屏幕底部打印该行,从而生成文本滚动,否则它应该可以工作。在这种情况下,您应该删除\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
    ...
}

同样,只要您的线条适合屏幕/窗口宽度,此方法就可以工作。

【讨论】:

  • 这不是 Go 语法,不要分享混有 Go 语言的伪代码。
猜你喜欢
  • 2012-06-22
  • 1970-01-01
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
  • 2013-05-01
相关资源
最近更新 更多