csv-to-json/main.go

64 lines
1.1 KiB
Go

package main
import (
"bytes"
"encoding/csv"
"encoding/json"
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
)
type replacer struct {
r io.Reader
}
func (r replacer) Read(b []byte) (int, error) {
n, err := r.r.Read(b)
c := bytes.ReplaceAll(b[:n], []byte("\r"), []byte("\n"))
c = bytes.ReplaceAll(c, []byte(`,="`), []byte(`,"`))
copy(b, c)
return len(c), err
}
func main() {
parser := csv.NewReader(replacer{os.Stdin})
fields, err := parser.Read()
if err != nil {
panic(err)
}
for i := range fields {
fields[i] = strings.TrimSpace(fields[i])
}
n := 0
for {
n += 1
line, err := parser.Read()
if err == io.EOF {
break
}
if err != nil && !strings.Contains(err.Error(), "wrong number of fields") {
panic(err)
}
for len(line) < len(fields) {
line = append(line, "null")
}
if len(line) != len(fields) {
log.Println("[WARN]", "line", n, "has", len(line), "fields but only", len(fields), "are known")
}
lineResult := map[string]string{}
for i := range line {
k := strconv.Itoa(i)
if i < len(fields) {
k = fields[i]
}
lineResult[k] = line[i]
}
b, _ := json.Marshal(lineResult)
fmt.Printf("%s\n", b)
}
}