我有一个文件Index.csv
,其中包含以下数据:
100
200
300
400
500
600
700
800
900
1000
我需要打印或保存新文件New.csv
CSV文件Original.csv
的行,如Original.csv
中所述。我该怎么做?
我无法做到,所以我将Index.csv
的内容复制到一个数组中,并编写了以下代码,但它不起作用:
array = [100,200,300,400,500,600,700,800,900,1000]
CSV.open('New.csv', "wb") do |csv|
f = File.open('Original.csv', "r")
f.each_line { |line|
row = line.split(",")
for i in 0..array.size
if array[i]==line
csv<<row
end
end
}
end
答案 0 :(得分:2)
您的问题中缺少详细信息,例如文件中有多少行,以及索引文件是否已排序。如果没有这些信息并假设最糟糕的文件和未分类的索引文件,我会使用类似这样的代码:
File.open('new.csv', 'w') do |new_csv|
File.foreach('index.csv') do |line_num|
File.open('original.csv', 'r') do |original_csv|
original_line = ''
line_num.to_i.times do
original_line = original_csv.gets
end
new_csv.puts original_line
end
end
end
假设index.csv为:
1
3
5
7
9
和original.csv:
row1
row2
row3
row4
row5
row6
row7
row8
row9
row10
运行代码会创建new.csv:
> cat new.csv
row1
row3
row5
row7
row9
CSV文件是文本,因此如果我们只关注各行,则无需使用CSV类来读取或写入它们。
可以使用readlines
进行更改并将输入文件和索引插入到生成的数组中,但这会导致代码不可扩展。建议的代码将导致重新读取index.csv中每行的original.csv,但它也会处理任意大小的文件,这在生产环境中非常重要。
例如,如果index.csv很小且未排序:
File.open('new.csv', 'w') do |new_csv|
indexes = File.readlines('index.csv').map(&:to_i).sort
File.foreach('original.csv').with_index(1) do |original_line, original_lineno|
new_csv.puts original_line if indexes.include?(original_lineno)
end
end
这样可以更快地运行,因为它只会遍历original.csv一次,但如果index.csv增长太大,则会出现潜在的可伸缩性问题。
答案 1 :(得分:1)
我会告诉你一种不用"Index.csv"
读取就行的方法。
array = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
i = array.shift
File.new("Original.csv").each_line.with_index(1) do
|l, j|
if j == i
puts l
i = array.shift
end
end