如何从另一个CSV文件中获取的索引的CSV文件中打印行

时间:2015-12-15 16:31:43

标签: ruby csv

我有一个文件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

2 个答案:

答案 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