github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/exp/freq/freq.go (about) 1 // Copyright 2013-2017 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Freq reads the given files (default standard input) and prints histograms of the 6 // character frequencies. By default, freq counts each byte as a character; under 7 // the –r option it instead counts UTF sequences, that is, runes. 8 // 9 // Synopsis: 10 // freq [-rdxoc] [FILES]... 11 // 12 // Description: 13 // Each non–zero entry of the table is printed preceded by the byte value, 14 // in decimal, octal, hex, and Unicode character (if printable). If any 15 // options are given, the –d, –x, –o, –c flags specify a subset of value 16 // formats: decimal, hex, octal, and character, respectively. 17 // 18 // Options: 19 // –r: treat input as UTF-8 20 // –d: print decimal value 21 // –x: print hex value 22 // –o: print octal value 23 // –c: print character/UTF value 24 package main 25 26 import ( 27 "bufio" 28 "flag" 29 "fmt" 30 "io" 31 "os" 32 "unicode/utf8" 33 ) 34 35 var utf = flag.Bool("r", false, "treat input as UTF-8") 36 var dec = flag.Bool("d", false, "print decimal value") 37 var hex = flag.Bool("x", false, "print hexadecimal value") 38 var oct = flag.Bool("o", false, "print octal value") 39 var chr = flag.Bool("c", false, "print character/rune") 40 41 var freq [utf8.MaxRune + 1]uint64 42 43 func doFreq(f *os.File) { 44 b := bufio.NewReaderSize(f, 8192) 45 46 var r rune 47 var c byte 48 var err error 49 if *utf { 50 for { 51 r, _, err = b.ReadRune() 52 if err != nil { 53 if err != io.EOF { 54 fmt.Fprintf(os.Stderr, "error reading: %v", err) 55 } 56 return 57 } 58 freq[r]++ 59 } 60 } else { 61 for { 62 c, err = b.ReadByte() 63 if err != nil { 64 if err != io.EOF { 65 fmt.Fprintf(os.Stderr, "error reading: %v", err) 66 } 67 return 68 } 69 freq[c]++ 70 } 71 } 72 } 73 74 func main() { 75 flag.Parse() 76 77 if flag.NArg() > 0 { 78 for _, v := range flag.Args() { 79 f, err := os.Open(v) 80 if err != nil { 81 fmt.Fprintf(os.Stderr, "open %s: %v", v, err) 82 os.Exit(1) 83 } 84 doFreq(f) 85 f.Close() 86 } 87 } else { 88 doFreq(os.Stdin) 89 } 90 91 if !(*dec || *hex || *oct || *chr) { 92 *dec, *hex, *oct, *chr = true, true, true, true 93 } 94 95 b := bufio.NewWriterSize(os.Stdout, 8192*4) 96 for i, v := range freq { 97 if v == 0 { 98 continue 99 } 100 101 if *dec { 102 fmt.Fprintf(b, "%3d ", i) 103 } 104 if *oct { 105 fmt.Fprintf(b, "%.3o ", i) 106 } 107 if *hex { 108 fmt.Fprintf(b, "%.2x ", i) 109 } 110 if *chr { 111 if i <= 0x20 || (i >= 0x7f && i < 0xa0) || (i > 0xff && !(*utf)) { 112 b.WriteString("- ") 113 } else { 114 b.WriteRune(rune(i)) 115 b.WriteString(" ") 116 } 117 } 118 fmt.Fprintf(b, "%8d\n", v) 119 } 120 b.Flush() 121 }