In the chapter, Human Readable Output, the topic of formatting is discussed. The following program can be examined, compiled, and run to better understand default formatting and using a flag to specify various formats.
Go
// Place this code in a main.go
package main
import (
"encoding/csv"
"encoding/json"
"fmt"
"os"
"text/tabwriter"
"github.com/olekukonko/tablewriter"
"github.com/spf13/pflag"
)
type Person struct {
LastName string `json:"last_name"`
FirstName string `json:"first_name"`
Street string `json:"street_address"`
City string `json:"city"`
State string `json:"state"`
}
var people = []Person{
{"Doe", "John", "123 Main St", "Springfield", "IL"},
{"Smith", "Jane", "456 Oak Ave", "Lincoln", "NE"},
{"Brown", "Charlie", "789 Pine Rd", "Salem", "OR"},
{"Johnson", "Mary", "321 Maple Dr", "Austin", "TX"},
{"Davis", "Robert", "654 Birch Ln", "Tampa", "FL"},
}
func main() {
var format string
pflag.StringVar(&format, "format", "text", "Output format: text, table, csv, json, pretty-json")
pflag.Parse()
switch format {
case "text":
printText(people)
case "table":
printTable(people)
case "csv":
printCSV(people)
case "json":
printJSON(people, false)
case "pretty-json":
printJSON(people, true)
default:
fmt.Fprintf(os.Stderr, "Unknown format: %s\n", format)
os.Exit(1)
}
}
func printText(data []Person) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintln(w, "Last Name\tFirst Name\tStreet Address\tCity\tState")
for _, p := range data {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", p.LastName, p.FirstName, p.Street, p.City, p.State)
}
w.Flush()
}
func printTable(data []Person) {
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Last Name", "First Name", "Street Address", "City", "State"})
for _, p := range data {
table.Append([]string{p.LastName, p.FirstName, p.Street, p.City, p.State})
}
table.Render()
}
func printCSV(data []Person) {
writer := csv.NewWriter(os.Stdout)
writer.Write([]string{"Last Name", "First Name", "Street Address", "City", "State"})
for _, p := range data {
writer.Write([]string{p.LastName, p.FirstName, p.Street, p.City, p.State})
}
writer.Flush()
}
func printJSON(data []Person, pretty bool) {
var output []byte
var err error
if pretty {
output, err = json.MarshalIndent(data, "", " ")
} else {
output, err = json.Marshal(data)
}
if err != nil {
fmt.Fprintf(os.Stderr, "JSON Error: %v\n", err)
os.Exit(1)
}
fmt.Println(string(output))
}
Expand
This program can be exampled by either compiling it or using “go run” as follows:
Bash
# To run compiled
go mod init hformat
go mod tidy
go build -o hformat main.go
./hformat --format=table
./hformat --format=text
./hformat --format=csv
./hformat --format=json
./hformat --format=pretty-json
# Or optionally run with go run
go run main.go --format=table
go run main.go --format=text
# ...etc
* Note: During the creation of this example code, problems were encountered with Tablewriter v1.0.8 . Opening go.mod and replacing v1.0.8 with v1.0.5 and running ‘go mod tidy’ should resolve any issues.
Bash
./hformat
Last Name First Name Street Address City State
Doe John 123 Main St Springfield IL
Smith Jane 456 Oak Ave Lincoln NE
Brown Charlie 789 Pine Rd Salem OR
Johnson Mary 321 Maple Dr Austin TX
Davis Robert 654 Birch Ln Tampa FL
./hformat --format=table
+-----------+------------+----------------+-------------+-------+
| LAST NAME | FIRST NAME | STREET ADDRESS | CITY | STATE |
+-----------+------------+----------------+-------------+-------+
| Doe | John | 123 Main St | Springfield | IL |
| Smith | Jane | 456 Oak Ave | Lincoln | NE |
| Brown | Charlie | 789 Pine Rd | Salem | OR |
| Johnson | Mary | 321 Maple Dr | Austin | TX |
| Davis | Robert | 654 Birch Ln | Tampa | FL |
+-----------+------------+----------------+-------------+-------+
./hformat --format=csv
Last Name,First Name,Street Address,City,State
Doe,John,123 Main St,Springfield,IL
Smith,Jane,456 Oak Ave,Lincoln,NE
Brown,Charlie,789 Pine Rd,Salem,OR
Johnson,Mary,321 Maple Dr,Austin,TX
Davis,Robert,654 Birch Ln,Tampa,FL
./hformat --format=csv
Last Name,First Name,Street Address,City,State
Doe,John,123 Main St,Springfield,IL
Smith,Jane,456 Oak Ave,Lincoln,NE
Brown,Charlie,789 Pine Rd,Salem,OR
Johnson,Mary,321 Maple Dr,Austin,TX
Davis,Robert,654 Birch Ln,Tampa,FL
./hformat --format=json
[{"last_name":"Doe","first_name":"John","street_address":"123 Main St","city":"Springfield","state":"IL"},{"last_name":"Smith","first_name":"Jane","street_address":"456 Oak Ave","city":"Lincoln","state":"NE"},{"last_name":"Brown","first_name":"Charlie","street_address":"789 Pine Rd","city":"Salem","state":"OR"},{"last_name":"Johnson","first_name":"Mary","street_address":"321 Maple Dr","city":"Austin","state":"TX"},{"last_name":"Davis","first_name":"Robert","street_address":"654 Birch Ln","city":"Tampa","state":"FL"}]
./hformat --format=pretty-json
[
{
"last_name": "Doe",
"first_name": "John",
"street_address": "123 Main St",
"city": "Springfield",
"state": "IL"
},
{
"last_name": "Smith",
"first_name": "Jane",
"street_address": "456 Oak Ave",
"city": "Lincoln",
"state": "NE"
},
. . . .