Go version
go version go1.23.3 darwin/arm64
Output of go env in your module/workspace:
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/gabriel.alvesdearruda/Library/Caches/go-build'
GOENV='/Users/gabriel.alvesdearruda/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/gabriel.alvesdearruda/go/pkg/mod'
GONOPROXY=''
GONOSUMDB='gitlab.thunes.com/*,gitlab.thunes.com/*/*'
GOOS='darwin'
GOPATH='/Users/gabriel.alvesdearruda/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.23.3/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.23.3/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.3'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/gabriel.alvesdearruda/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/gabriel.alvesdearruda/thunes/bootstrap/go-sftp-transfer/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/pk/_2923cl114q1vn9h63xgr3gc0000gr/T/go-build3215592430=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
The problem
When writing to a CSV file, I want to wrap certain strings in quotes, especially when the text contains spaces. However, this appears to be impossible.
The issue occurs because when calling the csv.Write function with an array containing manually escaped quotes (e.g., fmt.Sprintf("\"example\"")), the CSV writer inserts quotes at three different points:
-
When the condition !w.fieldNeedsQuotes(field) is met, the function immediately writes an opening quote (w.w.WriteByte('"');). This happens in encoding/csv/writer.go#L71.
-
When encoding special characters, the function escapes existing quotes (""), which occurs in encoding/csv/writer.go#L92.
-
Finally, the function writes a closing quote in encoding/csv/writer.go#L110.
As a result, the output in the CSV file ends up with triple quotes, like this:
"""example""", with three quotes.
Steps to reproduce
To reproduce the problem, I wrote this code:
package main
import (
"encoding/csv"
"fmt"
"os"
"strings"
)
func main() {
records := []string{"myfield1", "my nice field", "myfield3"}
quoted := quotedFields(records)
file, err := os.Create("./output.csv")
if err != nil {
panic(err)
}
writer := csv.NewWriter(file)
writer.Write(quoted)
writer.Flush()
}
func quotedFields(fields []string) []string {
result := make([]string, len(fields))
for i, v := range fields {
if strings.Contains(v, " ") {
result[i] = fmt.Sprintf("\"%s\"", v)
continue
}
result[i] = v
}
return result
}
Output file:
myfield1,"""my nice field""",myfield3
Expected Output:
myfield1,"my nice field",myfield3
What did you see happen?
Output file:
myfield1,"""my nice field""",myfield3
What did you expect to see?
Expected Output:
myfield1,"my nice field",myfield3
Go version
go version go1.23.3 darwin/arm64
Output of
go envin your module/workspace:What did you do?
The problem
When writing to a CSV file, I want to wrap certain strings in quotes, especially when the text contains spaces. However, this appears to be impossible.
The issue occurs because when calling the
csv.Writefunction with an array containing manually escaped quotes (e.g.,fmt.Sprintf("\"example\"")), the CSV writer inserts quotes at three different points:When the condition !w.fieldNeedsQuotes(field) is met, the function immediately writes an opening quote (w.w.WriteByte('"');). This happens in
encoding/csv/writer.go#L71.When encoding special characters, the function escapes existing quotes (""), which occurs in
encoding/csv/writer.go#L92.Finally, the function writes a closing quote in
encoding/csv/writer.go#L110.As a result, the output in the CSV file ends up with triple quotes, like this:
"""example""", with three quotes.Steps to reproduce
To reproduce the problem, I wrote this code:
Output file:
Expected Output:
What did you see happen?
Output file:
What did you expect to see?
Expected Output: