如何在 Ruby 中创建一个 CSV 文件的某些列的副本,并在一个列中使用不同的数据?

我有个 CSV 文件叫“ A.CSV”。我需要用来自“ A.CSV”的数据生成一个名为“ B.CSV”的新 CSV 文件。

我将使用“ A.csv”中的一个列子集,并且必须将一个列的值更新为“ B.csv”中的新值。最后,我将使用来自 B.csv 的数据对数据库进行验证。

  1. 如何创建新的 CSV 文件?
  2. 如何将所需列的数据从 A.csv 复制到“ B.csv”?
  3. 如何为特定列追加值?

我是 Ruby 的新手,但我能够通过读取 CSV 来获得数组或散列。

88825 次浏览

Have you seen Ruby's CSV class? It seems pretty comprehensive. Check it out here: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html

As mikeb pointed out, there are the docs - http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html - Or you can follow along with the examples below (all are tested and working):

To create a new file:

In this file we'll have two rows, a header row and data row, very simple CSV:

require "csv"
CSV.open("file.csv", "wb") do |csv|
csv << ["animal", "count", "price"]
csv << ["fox", "1", "$90.00"]
end

result, a file called "file.csv" with the following:

animal,count,price
fox,1,$90.00

How to append data to a CSV

Almost the same formula as above only instead of using "wb" mode, we'll use "a+" mode. For more information on these see this stack overflow answer: What are the Ruby File.open modes and options?

CSV.open("file.csv", "a+") do |csv|
csv << ["cow", "3","2500"]
end

Now when we open our file.csv we have:

animal,count,price
fox,1,$90.00
cow,3,2500

Read from our CSV file

Now you know how to copy and to write to a file, to read a CSV and therefore grab the data for manipulation you just do:

CSV.foreach("file.csv") do |row|
puts row #first row would be ["animal", "count", "price"] - etc.
end

Of course, this is like one of like a hundred different ways you can pull info from a CSV using this gem. For more info, I suggest visiting the docs now that you have a primer: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html

You will probably want to use CSV::parse to help Ruby understand your CSV as the table of data that it is and enable easy access to values by header.

Unfortunately, the available documentation on the CSV::parse method doesn't make it very clear how to actually use it for this purpose.

I had a similar task and was helped much more by How to Read & Parse CSV Files With Ruby on rubyguides.com than by the CSV class documentation or by the answers pointing to it from here.

I recommend reading that page in its entirety. The crucial part is about transforming a given CSV into a CSV::Table object using:

table = CSV.parse(File.read("cats.csv"), headers: true)

Now there's documentation on the CSV::Table class, but again you might be helped more by the clear examples on the rubyguides.com page. One thing I'll highlight is that when you tell .parse to expect headers, the resulting table will treat the first row of data as row [0].

You will probably be especially interested in the .by_col method available for your new Table object. This will allow you to iterate through different column index positions in the input and/or output and either copy from one to the other or add a new value to the output. If I get it working, I'll come back and post an example.