我试图将新列附加到现有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格式的情况下追加?
答案 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