This is an education project that attempts to reimplement the GNU coreutils in Go. You can find the full manual here:
https://www.gnu.org/software/coreutils/manual/coreutils.html
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.1 KiB
62 lines
1.1 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"flag"
|
|
"os"
|
|
"log"
|
|
"strings"
|
|
)
|
|
|
|
func Fail(err error, format string, v ...any) {
|
|
err_format := fmt.Sprintf("ERROR: %v; %s", err, format)
|
|
log.Printf(err_format, v...)
|
|
os.Exit(1)
|
|
}
|
|
|
|
type Opts struct {
|
|
Number bool
|
|
Squeeze bool
|
|
Filenames []string
|
|
}
|
|
|
|
func parse_opts() (Opts) {
|
|
var opts Opts
|
|
|
|
flag.BoolVar(&opts.Number, "n", false, "Number all nonempty output lines, starting with 1")
|
|
flag.BoolVar(&opts.Squeeze, "s", false, "Suppress repeated adjacent blank lines")
|
|
flag.Parse()
|
|
|
|
if flag.NArg() < 1 {
|
|
log.Fatal("USAGE: cat [-n] [-s] file0 [fileN]")
|
|
os.Exit(1)
|
|
}
|
|
|
|
opts.Filenames = flag.Args()
|
|
|
|
return opts
|
|
}
|
|
|
|
func main() {
|
|
opts := parse_opts()
|
|
|
|
for _, filename := range opts.Filenames {
|
|
in_file, err := os.ReadFile(filename)
|
|
|
|
if err != nil { Fail(err, "cannot open %s:", filename) }
|
|
|
|
if(opts.Number) {
|
|
count := 1
|
|
for line := range strings.Lines(string(in_file)) {
|
|
if opts.Squeeze && len(line) <= 1 {
|
|
continue
|
|
}
|
|
|
|
fmt.Printf("%0.4d: %s", count, line)
|
|
count++
|
|
}
|
|
} else {
|
|
fmt.Print(string(in_file))
|
|
}
|
|
}
|
|
}
|
|
|