Riaan's SysAdmin Blog

My tips, howtos, gotchas, snippets and stuff. Use at your own risk!


Go Format Output Column Style

Similar to this article (using python) https://blog.ls-al.com/python-output-align-by-column/ I also did a quick Golang implementation.

It is not quite as done as I would like but it is reasonably close. Similar to the python article the idea is to use something like an array to store column header descriptions and a value on how long the output strings should be and use it for header printing as well as line output statements.

In addition I am doing some file operations here to create the output so the article has additional value.

package main

import (

type rec struct {
  fname, fsize string

var i int64
var files map[int64]rec
var FORMAT map[string]int 

func PadLeft(str, pad string, length int) string {
  for {
   str = pad + str
   if len(str) > length {
     return str[0:length]

func printHeader(FORMAT map[string]int) {
  for k, v := range FORMAT {
    fmt.Printf("%[1]*[2]s ",v ,k)    
  for k, v := range FORMAT {
    _ = k
    //fmt.Printf("% [1]*[2]s ",v, "#")
    fmt.Printf("%s   ",PadLeft("","#",v))    

func visit(path string, f os.FileInfo, err error) error {
  fi, e := os.Stat(path)
  if e != nil {
    return e
  i = i + 1
  files[i] = rec{path, strconv.Itoa(int(fi.Size()))}
  return nil

func main() {
  FORMAT := map[string]int{"File Size": 10, "File Name": 11}
  files = make(map[int64]rec)
  root := flag.Arg(0)
  err := filepath.Walk(root, visit)
  _ = err
  //fmt.Printf("filepath.Walk() returned %v\n", err)
  for k, v := range files {
    _ = k
    fmt.Printf("%[1]*[2]s   %[3]*[4]s\n", FORMAT["File Size"], v.fsize, FORMAT["File Name"], v.fname)

Test Run

$ go run header.go /etc/default/
 File Size   File Name 
##########   ###########   
       346   /etc/default/acpid
       290   /etc/default/anacron
       209   /etc/default/saned
       149   /etc/default/apport
       132   /etc/default/speech-dispatcher


Bio Info for Riaan