|
|
|
@ -14,30 +14,39 @@ func Fail(err error, format string, v ...any) { |
|
|
|
|
os.Exit(1) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func main() { |
|
|
|
|
var number bool |
|
|
|
|
var squeeze bool |
|
|
|
|
type Opts struct { |
|
|
|
|
Number bool |
|
|
|
|
Squeeze bool |
|
|
|
|
Filename string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
flag.BoolVar(&number, "n", false, "Number all nonempty output lines, starting with 1") |
|
|
|
|
flag.BoolVar(&number, "number", false, "Number all nonempty output lines, starting with 1") |
|
|
|
|
flag.BoolVar(&squeeze, "s", false, "Suppress repeated adjacnet blank lines") |
|
|
|
|
flag.BoolVar(&squeeze, "squeeze-blank", false, "Suppress repeated adjacnet blank lines") |
|
|
|
|
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/--number] file0 [fileN]") |
|
|
|
|
log.Fatal("USAGE: cat [-n] [-s] file0 [fileN]") |
|
|
|
|
os.Exit(1) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
filename := flag.Arg(0) |
|
|
|
|
in_file, err := os.ReadFile(filename) |
|
|
|
|
opts.Filename = flag.Arg(0) |
|
|
|
|
|
|
|
|
|
return opts |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func main() { |
|
|
|
|
opts := parse_opts() |
|
|
|
|
in_file, err := os.ReadFile(opts.Filename) |
|
|
|
|
|
|
|
|
|
if err != nil { Fail(err, "cannot open %s:", filename) } |
|
|
|
|
if err != nil { Fail(err, "cannot open %s:", opts.Filename) } |
|
|
|
|
|
|
|
|
|
if(number) { |
|
|
|
|
if(opts.Number) { |
|
|
|
|
count := 1 |
|
|
|
|
for line := range strings.Lines(string(in_file)) { |
|
|
|
|
if squeeze && len(line) <= 1 { |
|
|
|
|
if opts.Squeeze && len(line) <= 1 { |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|