package main import ( "fmt" "os" "flag" "log" "bufio" ) type Opts struct { Width int Filenames []string Hex bool Octal bool Format string } func ParseOpts(args []string) (Opts) { var opts Opts myflags := flag.NewFlagSet("od", flag.ContinueOnError) myflags.IntVar(&opts.Width, "w", 16, "Width of output grid") myflags.BoolVar(&opts.Hex, "x", false, "Output hex bytes") myflags.BoolVar(&opts.Octal, "o", false, "Output octal bytes") myflags.Parse(args[1:]) if myflags.NArg() == 0 { log.Fatal("USAGE: od [files]") } if opts.Hex { opts.Format = "%0.2x " } else { opts.Format = "%0.3o " } opts.Filenames = myflags.Args() return opts } func main() { opts := ParseOpts(os.Args) for _, filename := range opts.Filenames { reader, err := os.Open(filename) defer reader.Close() if err != nil { log.Fatalf("can't open: %s: %v", filename, err) } buf := bufio.NewReader(reader) count := buf.Size() fmt.Printf("%0.8o ", 0); for index := 0; index < count; index++ { data, err := buf.ReadByte() if err != nil { break } fmt.Printf(opts.Format, data); if (index + 1) % opts.Width == 0 { fmt.Print("\n") fmt.Printf("%0.8o ", index); } } } }