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)) } } }