LoginSignup
3
2

More than 5 years have passed since last update.

CSV出力で空文字だけダブルクオートつけられてつらい時

Posted at

タブ区切りのファイルを出力して、それをmysqlにloadする処理を作ったら、空文字が「""」と入ってしまうデータがあった。
調べてみたら、nilの出力は空文字だが、空文字の出力は「""」になってしまうもよう。

  • 検証プログラム
require 'csv'

data = [[1, "XXX", nil, "", " ", 111],[2, "YYY", nil, "", "  ", 222]]

CSV.open("out.csv","w", col_sep: "\t") do |out|
  data.each do |d|
    out << d
  end
end

out_csv = File.read("out.csv")
puts "out.csv.inspect=" + out_csv.inspect
puts "out.csv.to_s=\n----\n" + out_csv.to_s + "\n----"
  • 結果
out.csv.inspect="1\tXXX\t\t\"\"\t \t111\n2\tYYY\t\t\"\"\t  \t222\n"
out.csv.to_s=
----
1       XXX             ""              111
2       YYY             ""              222

----

1文字以上の文字列はつけないけど、空文字はつけるとかなんで???

force_quotesでいっそ全部ダブルクオートつけるか、CSV::Convertersとか使ってデータごとに形式を決めるのが正しいのかもしれないのだけど面倒なので、空文字は全部nilに変えてしまうことにした。

  • 検証プログラム
require 'csv'

data = [[1, "XXX", nil, "", " ", 111],[2, "YYY", nil, "", "  ", 222]]

CSV.open("out.csv","w", col_sep: "\t") do |out|
  data.each do |d|
    #out << d
    out << d.map{|_d| _d.to_s == "" ? nil : _d}
  end
end

out_csv = File.read("out.csv")
puts "out.csv.inspect=" + out_csv.inspect
puts "out.csv.to_s=\n----\n" + out_csv.to_s + "\n----"
  • 結果
out.csv.inspect="1\tXXX\t\t\t \t111\n2\tYYY\t\t\t  \t222\n"
out.csv.to_s=
----
1       XXX                             111
2       YYY                             222

----
3
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2