在ruby中为.csv的每一行添加新列

时间:2015-03-18 15:28:04

标签: ruby csv

我试图将新列附加到现有csv文件的每一行。以下代码执行我想要的:

csv_info = CSV.read("foo.csv")
csv_info.each do |info|
  info << new_object
end
当我使用pry时,

在内存中给我以下内容:

[[uuid0, account0, url0, new_object],
 [uuid1, account1, url1, new_object]]

这不会写入文件,因为它是CSV.read而不是CSV.open("foo.csv","w")。当我尝试使用csv_info对象写入文件时:

csv_info = CSV.read("foo.csv")
csv_info.each do |info|
  info << new_object
end
CSV.open("foo.csv", "w") do |old_csv|
  old_csv << csv_info
end

文件最终结束:

[["[\"<uuid0>\", \"<account0>\", \"<url0>\", \"<new_object>\"]",
   "[\"<uuid1>\", \"<account1>\", \"<url1>\", \"<new_object>\"]"]]

如何在不影响csv格式的情况下追加?

2 个答案:

答案 0 :(得分:4)

在您的示例中,您正在阅读整个CSV并在内存中对其进行操作。相反,我建议一次读取和修改一行,特别是如果CSV文件很大。

以下是如何逐行修改临时文件,然后将原始文件替换为生成的临时文件。

require "csv"
require "fileutils"
require "tempfile"

temp = Tempfile.new("csv")

CSV.open(temp, "w") do |temp_csv|
  CSV.foreach("foo.csv") do |orig|
    temp_csv << orig + ["new_object"]
  end
end

FileUtils.mv(temp, "foo.csv", :force => true)

答案 1 :(得分:1)

CSV#<<需要一行:

CSV.generate { |csv| csv << [1, 2, 3] }
#=> "1,2,3\n"

CSV.generate { |csv| csv << [1, 2, 3] << [4, 5, 6] }
#=> "1,2,3\n4,5,6\n"

但你传递的是一个二维数组(不能按预期工作):

CSV.generate { |csv| csv << [[1, 2, 3], [4, 5, 6]] }
#=> "\"[1, 2, 3]\",\"[4, 5, 6]\"\n"

所以而不是:

old_csv << csv_info

你需要这样的东西:

csv_info.each do |info|
  old_csv << info
end