Skip to content

Instantly share code, notes, and snippets.

@b5
Created February 27, 2018 00:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save b5/78edaae9e6a4248ea06b45d089c277d6 to your computer and use it in GitHub Desktop.
Save b5/78edaae9e6a4248ea06b45d089c277d6 to your computer and use it in GitHub Desktop.
Dealing with Solo Carriage Returns in csv.Reader
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"encoding/csv"
)
// ReplaceSoloCarriageReturns wraps an io.Reader, on every call of Read it
// for instances of lonely \r replacing them with \r\n before returning to the end customer
// lots of files in the wild will come without "proper" line breaks, which irritates go's
// standard csv package. This'll fix by wrapping the reader passed to csv.NewReader:
// rdr, err := csv.NewReader(ReplaceSoloCarriageReturns(r))
//
func ReplaceSoloCarriageReturns(data io.Reader) io.Reader {
return crlfReplaceReader{
rdr: bufio.NewReader(data),
}
}
// crlfReplaceReader wraps a reader
type crlfReplaceReader struct {
rdr *bufio.Reader
}
// Read implements io.Reader for crlfReplaceReader
func (c crlfReplaceReader) Read(p []byte) (n int, err error) {
if len(p) == 0 {
return
}
for {
if n == len(p) {
return
}
p[n], err = c.rdr.ReadByte()
if err != nil {
return
}
// any time we encounter \r & still have space, check to see if \n follows
// if next char is not \n, add it in manually
if p[n] == '\r' && n < len(p) {
if pk, err := c.rdr.Peek(1); (err == nil && pk[0] != '\n') || (err != nil && err.Error() == io.EOF.Error()) {
n++
p[n] = '\n'
}
}
n++
}
return
}
var csvData = []byte("col_0,col_1,col_2\ra,b,c\rd,e,f\rg,h,i\r")
// also online in the go playground: https://play.golang.org/p/Yy0xJtcMrG4
func main() {
file := bytes.NewReader(csvData)
rdr := csv.NewReader(ReplaceSoloCarriageReturns(file))
for {
rec, err := rdr.Read()
if err != nil {
// real programs handle errors
return
}
fmt.Println(rec)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment