我有一个包含两列数字的长CSV文件:
1,2
2,5
7,3
etc...
我想添加第三列,等于前两位的总和:
1,2,3
2,5,7
7,3,10
以下代码是问题的解决方案,它会复制输入文件,并附加第三列。相反,我想逐行操作输入文件,在我进行时将第三列写入每一行。如果进程因某种原因出错,则应该已经保存了文件前半部分的答案,不需要重新计算。
我无法使用ruby的CSV
课程来提供一个很好的方法。这是我目前使用复制文件的解决方案:
require 'csv'
CSV.open("big_file.csv", "w") do |csv|
csv << %w{1 2}
csv << %w{2 5}
csv << %w{3 8}
end
big_csv_file = CSV.open("big_file.csv", 'r')
# I'm creating a copy of big_file.csv here
# I'd rather edit it in place
CSV.open("copy_with_extra_column.csv", "w") do |csv|
big_csv_file.each do |row|
row << eval(row[0] + row[1])
csv << row
end
end
答案 0 :(得分:1)
文件就像一个长字符串,例如:
1,2\n2,5
但是,与字符串不同,您只能覆盖文件中的字符。在上面的示例中,有7个字符。您可以使用您选择的任何字符覆盖任何这些字符。因此,例如,如果您将数字之和放在位置0和位置2到位置3,结果是:
1,232,5
这可能不是你想要的,因为看起来前两个数字分别是1和232,它们的总和是5.但是,这就是你在地方编辑文件时所能做的:你只能覆盖字符与其他角色。
对于大文件,您可以读取一行,然后将更改的行写入新文件。完成后,您可以删除原始文件,然后可以将新文件重命名为旧文件名。您可以使用Tempfile类来避免新文件名的名称冲突。
答案 1 :(得分:1)
换句话说,在基本文件级别,没有办法将总和“插入”到文件中。在您的示例中:
1,2
2,5
7,2
如果我们忽略“CSV”文件的整个概念(实际上只是在流文本文件之上分层的概念)要在第一行的末尾“插入”文本,3
,我们需要做所有这些事情:
然后,您将为每个额外的行重复此过程。
这显然效率很低。简单来说,CSV文件格式不是为有效插入数据而设计的。
您的两个选择是:
“就地”更新文件是不切实际的。
答案 2 :(得分:0)
而不是CSV.open()
,请尝试CSV.read()
。例如,它显然有点难看,但是:
big_csv_file = CSV.read("big_file.csv")
big_csv_file[0] << eval(big_csv_file[0][0] + big_csv_file[0][1])
CSV.open("copy_with_extra_column.csv", "w") do |csv|
big_csv_file.each do |row|
csv << row
end
end
如果你需要文件始终是最新的,那么显然需要改变和写作。