6

I am iterating over an array and printing a formatted string with each array element to the terminal (stdout). Rather than printing each element on a new line, I want to overwrite the previous output with the program's newest output.

I am using macosx.

I have tried a few ways:

// '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()
}

A second way was to remove \r from the string and add and additional Printf before each output: fmt.Printf("\033[0;0H").

2
  • 6
    What happens if you remove the '\n' from the end of the string? Commented May 12, 2019 at 22:51
  • 1
    I removed the \n. Oddly enough on some lines the stdout is overwritten but on most it is still not working. I also removed the code from the bytes package. It seems it is no longer needed. Commented May 13, 2019 at 1:45

1 Answer 1

14

You can use the ANSI Escape Codes

First, save the position of the cursor with fmt.Print("\033[s"), then for each line, restore the position and clear the line before printing the line with fmt.Print("\033[u\033[K")

Your code could be:

// 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)
    }
    ...
}

It should work unless your program prints the line at the bottom of the screen, generating a scrolling of your text. In this case, you should remove the \n and make sure that no line exceeds the screen (or window) width.

Another option could be to move the cursor up after each write:

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
    ...
}

Again, this works as long as your line fits on the screen/window width.

Sign up to request clarification or add additional context in comments.

1 Comment

This is not Go syntax, don't share pseudo code mixed with Go language.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.