Video Coming Soon...
41: cut
The cut command takes input that's "tabular" and cut it into columns to display. It's a very useful tool when you have data that you only want a slice of, but don't want to write a little program to do the slicing.
The Challenge
To get your version of cut working you'll need to implement these options:
-f-- Sets the list of fields to output.-d-- Sets what character delimits (separates) the fields. By default this is\t.
The documentation for cut is at:
Requirements
You'll find that cut doesn't use anything new, but it does use almost everything you've seen:
See the list of requirements
- fmt -- https://pkg.go.dev/fmt
- flag -- https://pkg.go.dev/flag
- strings -- https://pkg.go.dev/strings
- log -- https://pkg.go.dev/log
- strconv -- https://pkg.go.dev/strconv
- bufio -- https://pkg.go.dev/bufio
- os -- https://pkg.go.dev/os
Spoilers
As usual, here's my first implementation of cut. Can you do better?
See my first version code
View Source file go-coreutils/cut/main.go Onlypackage main
import (
"fmt"
"flag"
"strings"
"log"
"strconv"
"bufio"
"os"
)
type Opts struct {
FieldOpt string
Fields []int
Delim string
}
func ParseOpts() Opts {
var opts Opts
opts.Fields = make([]int, 0, 10)
flag.StringVar(&opts.FieldOpt, "f", "", "fields list")
flag.StringVar(&opts.Delim, "d", "\t", "delimiter byte")
flag.Parse()
if opts.FieldOpt == "" { log.Fatal("-f fields list required") }
for _, num := range strings.Split(opts.FieldOpt, ",") {
as_int, err := strconv.Atoi(num)
if err != nil { log.Fatal("-f can only contain numbers") }
opts.Fields = append(opts.Fields, as_int)
}
return opts
}
func main() {
opts := ParseOpts()
scan := bufio.NewScanner(os.Stdin)
for scan.Scan() {
line := scan.Text()
chopped := strings.Split(line, opts.Delim)
for i, field_num := range opts.Fields {
if field_num >= len(chopped) {
fmt.Print("\n")
continue
}
fmt.Print(chopped[field_num])
if i < len(opts.Fields) - 1 {
fmt.Print(opts.Delim)
} else {
fmt.Print("\n")
}
}
}
}
Testing It
If you want to push your learning further then you can try to implement an automated test for this. I actually need to learn how to test utilities like this with Go, so for now just consider this an extra challenge for later until I learn how to teach it.
Register for Learn Go the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.