Advertisement
Guest User

Untitled

a guest
May 21st, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.38 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "encoding/csv"
  5. "flag"
  6. "fmt"
  7. "io"
  8. "os"
  9. "strconv"
  10. "strings"
  11.  
  12. "github.com/midbel/linewriter"
  13. "github.com/midbel/sizefmt"
  14. "github.com/midbel/timefmt"
  15. )
  16.  
  17. type Column struct {
  18. Index int
  19. Type string
  20. In string
  21. Out string
  22. }
  23.  
  24. func (c Column) Parse(vs []string) error {
  25. v := strings.TrimSpace(vs[c.Index])
  26. switch c.Type {
  27. case "date", "datetime":
  28. w := timefmt.Parse(v, c.In)
  29. vs[c.Index] = timefmt.Format(w, c.Out)
  30. case "size":
  31. n, err := strconv.ParseFloat(v, 64)
  32. if err != nil {
  33. return err
  34. }
  35. vs[c.Index] = sizefmt.Format(n, sizefmt.IEC)
  36. default:
  37. }
  38. return nil
  39. }
  40.  
  41. func main() {
  42. comma := flag.Bool("c", false, "csv format")
  43. sep := flag.String("separator", "", "csv separator")
  44. flag.Parse()
  45. var r io.Reader
  46. if file := flag.Arg(0); flag.NArg() == 0 || file == "-" {
  47. r = os.Stdin
  48. } else {
  49. f, err := os.Open(flag.Arg(0))
  50. if err != nil {
  51. fmt.Fprintln(os.Stderr, err)
  52. os.Exit(1)
  53. }
  54. defer f.Close()
  55.  
  56. r = f
  57. }
  58.  
  59. cs := make([]Column, flag.NArg()-1)
  60. for i := 1; i < flag.NArg(); i++ {
  61. c, err := parseFormat(flag.Arg(i))
  62. if err != nil {
  63. fmt.Fprintln(os.Stderr, err)
  64. os.Exit(2)
  65. }
  66. cs[i-1] = *c
  67. }
  68.  
  69. line := Line(*comma)
  70. rs := csv.NewReader(r)
  71. if *sep != "" {
  72. rs.Comma = []rune(*sep)[0] //','
  73. }
  74. for {
  75. records, err := rs.Read()
  76. if err == io.EOF {
  77. break
  78. }
  79. if err != nil {
  80. fmt.Fprintln(os.Stderr, err)
  81. os.Exit(3)
  82. }
  83.  
  84. for i := 0; i < len(cs); i++ {
  85. if err := cs[i].Parse(records); err != nil {
  86. fmt.Fprintln(os.Stderr, err)
  87. os.Exit(4)
  88. }
  89. }
  90. for i := 0; i < len(records); i++ {
  91. line.AppendString(records[i], 12, linewriter.AlignRight)
  92. }
  93. io.Copy(os.Stdout, line)
  94. }
  95. }
  96.  
  97. func Line(comma bool) *linewriter.Writer {
  98. var options []linewriter.Option
  99. if comma {
  100. options = append(options, linewriter.AsCSV(false))
  101. } else {
  102. options = []linewriter.Option{
  103. linewriter.WithPadding([]byte(" ")),
  104. linewriter.WithSeparator([]byte("|")),
  105. }
  106. }
  107. return linewriter.NewWriter(4096, options...)
  108. }
  109.  
  110. func parseFormat(v string) (*Column, error) {
  111. var (
  112. c Column
  113. err error
  114. )
  115.  
  116. vs := strings.Split(v, ":")
  117. c.Index, err = strconv.Atoi(vs[0])
  118. if err != nil {
  119. return nil, err
  120. }
  121. c.Index--
  122. if c.Index < 0 {
  123. return nil, fmt.Errorf("invalid index: %s", v)
  124. }
  125. if len(vs) > 1 {
  126. c.Type = vs[1]
  127. switch c.Type {
  128. case "date", "datetime":
  129. c.In = vs[2]
  130. c.Out = vs[3]
  131. case "size":
  132. default:
  133. }
  134. }
  135.  
  136. return &c, nil
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement