The unix pipe operator is magical.
As long as you write your application to read input from standard-in and write output to standard-out you can compose your cli tool with thousands of other tools.
Scanners
To read one line at a time I like to use bufio.NewScanner. This uses bufio.ScanLines to split the reader by new lines.
in := bufio.NewScanner(os.Stdin) // Scan returns false when its out of lines for in.Scan() { // line is a string line := in.Text() // if you want bytes in.Bytes() exists too }
Lets build a tool
As an example here is a tiny command line tool I wrote to read urls for images and display them as ascii art images on the terminal.
Full source https://gist.github.com/trashhalo/6154a690bd2612ae33c8252d8051eb9f
func main() { in := bufio.NewScanner(os.Stdin) for in.Scan() { line := in.Text() err := convertLineToArt(line) if err != nil } } func convertLineToArt(line string) error { fmt.Println(line) resp, err := http.Get(line) if err != nil { defer resp.Body.Close() img, _, err := image.Decode(resp.Body) convertOptions := convert.DefaultOptions convertOptions.FixedWidth = 50 convertOptions.FixedHeight = 50 converter := convert.NewImageConverter() for _, row := range converter.Image2ASCIIMatrix(img, &convertOptions) { fmt.Print(row) } return nil }
Use Pipe
Now lets combine together a few tools.
curl -A "test" https://www.reddit.com/r/cats.json | jq -r '.data.children[] | .data.url'|go run .|less
This is saying:
Top comments (0)