Search code examples
gonewlinecarriage-return

Clearing the rest of the line while printing from Go program in Linux/macOS terminal and using carriage return


If I create a loop in Go like this:

package main

import (
    "fmt"
    "time"
)

func main() {
    for i := 10; i >= 0; i-- {
        fmt.Printf("Time out in %d seconds\r", i)
        time.Sleep(1 * time.Second)
    }
}

and run the program in Linux or macOS terminal, I will see the line printed in the first iteration correctly (Time out in 10 seconds) but in the next iteration (and every other in this case), since the string to print is one character shorter, I will see the leftovers from previous iteration as an additional s character in the end - Time out in 9 secondss, Time out in 8 secondss, etc.

Is there a simple way to clear printed line from previous iteration before printing out next line?


Solution

  • To specify the width of an integer, use a number after the % in the verb. By default, the result will be right-justified and padded with spaces.

    Use %2d instead of %d. It will fix your problem.

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        for i := 10; i >= 0; i-- {
            fmt.Printf("Time out in %2d seconds\r", i)
            time.Sleep(1 * time.Second)
        }
    }
    
    

    Update:

    You can also execute printf '\33c\e[3J' command from your go code to clean up the terminal.

    package main
    
    import (
        "fmt"
        "os"
        "os/exec"
        "time"
    )
    
    var clearScreen = func() {
        cmd := exec.Command(`printf '\33c\e[3J'`) // clears the scrollback buffer as well as the screen.
        cmd.Stdout = os.Stdout
        cmd.Run()
    }
    
    func main() {
        for i := 10; i >= 0; i-- {
            fmt.Printf("Time out in %2d seconds\r", i)
            time.Sleep(1 * time.Second)
            clearScreen()
        }
    }