🌊
Golangでフィールド数が可変のCSVを読み込む
背景
とある銀行の振込結果をインポートする必要がありまして、そのCSVのフォーマットがヘッダーなしで一行目に自身の情報(っぽいやつ)、二行目以降に振込結果が入ってるものだった。
極端だけどこんな感じ。
123,test@example.com,ヤマダタロウ
aaa,bbb,ccc
ddd,eee,fff,ggg
hhh,iii,jjj,kkk,lll
この二行目以降のデータが欲しい。
コード
とりあえず読み込んでみる。
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"os"
)
func main() {
file, err := os.Open("test.csv")
if err == io.EOF {
log.Fatalln(err)
}
r := csv.NewReader(file)
// 一行目を読み飛ばす
_, err = r.Read()
if err == io.EOF {
log.Fatalln(err)
}
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatalln(err)
}
fmt.Println(record)
}
}
実行
$ go run main.go
[aaa bbb ccc]
2021/08/23 23:33:54 record on line 3: wrong number of fields
exit status 1
どうやらフィールドの数が揃ってないとエラーになるらしい。困った。
パッケージのドキュメントを読んでみる
encoding/csv
のドキュメント
すると、type Reader
にこんなものを発見
type Reader struct {
...
// FieldsPerRecord is the number of expected fields per record.
// If FieldsPerRecord is positive, Read requires each record to
// have the given number of fields. If FieldsPerRecord is 0, Read sets it to
// the number of fields in the first record, so that future records must
// have the same field count. If FieldsPerRecord is negative, no check is
// made and records may have a variable number of fields.
FieldsPerRecord int
...
}
こいつに負の値を入れたらうまいことやってくれそうな雰囲気。
試してみる
func main() {
file, err := os.Open("test.csv")
if err == io.EOF {
log.Fatalln(err)
}
r := csv.NewReader(file)
r.FieldsPerRecord = -1 // 追加
// 一行目を読み飛ばす
_, err = r.Read()
if err == io.EOF {
log.Fatalln(err)
}
for {
...
}
}
実行
$ go run main.go
[aaa bbb ccc]
[ddd eee fff ggg]
[hhh iii jjj kkk lll]
読めた読めた。
Discussion