75 lines
1.5 KiB
Go
75 lines
1.5 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])
|
|
}
|
|
for i := range fields {
|
|
for j := i + 1; j < len(fields); j++ {
|
|
if fields[i] == fields[j] {
|
|
fields[i] = fmt.Sprintf("%s[%d]", fields[i], i)
|
|
fields[j] = fmt.Sprintf("%s[%d]", fields[j], j)
|
|
}
|
|
}
|
|
}
|
|
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]
|
|
}
|
|
if _, ok := lineResult[k]; ok {
|
|
k = fmt.Sprintf("%s[%d]", k, i)
|
|
}
|
|
lineResult[k] = strings.TrimSpace(line[i])
|
|
}
|
|
b, _ := json.Marshal(lineResult)
|
|
fmt.Printf("%s\n", b)
|
|
}
|
|
}
|