我如何使用Ruby将一个csv映射到另一个

时间:2019-03-20 03:54:04

标签: ruby csv

我有两个具有不同标题的csv。

让我们说csv 1具有标题1、2、3、4,而我想创建一个具有标题5、6、7、8的csv。

我很难编写代码来打开第一个CSV,然后创建第二个CSV。

这是我当前拥有的代码。

require 'csv'

wmj_headers = [
  "Project Number", 
  "Task ID",    
  "Task Name",
  "Status Comment", 
  "Act Complete", 
  "Plan Complete", 
  "Description"]

jir_headers_hash = {
  "Summary" => "Task Name",
  "Issue key" => "Status Comment",
  "Resolved" => "Act Complete",
  "Due date" => "Plan Complete",
  "Description" => "Description"
}
puts "Enter path to a directory of .csv files"
dir_path = gets.chomp
csv_file_names = Dir["#{dir_path}*.csv"]

csv_file_names.each do |f_path|
  base_name = File.basename(f_path, '.csv')
  wmj_name = "#{base_name}_wmj.csv"

  arr = []
  mycount = 0
  CSV.open(wmj_name, "wb") do |row| 
    row << wmj_headers 


    CSV.foreach(f_path, :headers => true) do |r|
      r.headers.each do |value|
        if jir_headers_hash[value].nil? == false
          arr << r[value]
        end
      end
    end 
    row << arr
  end
end

2 个答案:

答案 0 :(得分:2)

人们倾向于使事情变得过于复杂。您完全不需要任何CSV处理即可替换标题。

$ cat /tmp/src.csv
one,two,three
1,2,3
4,5,6

让标题和 stream 替换所有其他未触及的内容。

subst = {"one" => "ONE", "two" => "TWO", "three" => "THREE"}
src, dest = %w[/tmp/src.csv /tmp/dest.csv].map { |f| File.new f, "a+" }
headers = src.readline() # read just headers
dest.write(headers.gsub(/\b(#{Regexp.union(subst.keys)})\b/, )) # write headers
IO.copy_stream(src, dest, -1, headers.length) # stream the rest
[src, dest].each(&:close)

检查:

$ cat /tmp/dest.csv
ONE,TWO,THREE
1,2,3
4,5,6

答案 1 :(得分:0)

如果要替换CSV列名称,则为:

require 'csv'

# [["one", "two", "three"], ["1", "2", "3"], ["4", "5", "6"]]
csv = CSV.read('data.csv')

# new keys
ks = ['k1', 'k2', 'k3']

# [["k1", "k2", "k3"], ["1", "2", "3"], ["4", "5", "6"]]
k = csv.transpose.each_with_index.map do |x,i|
  x[0] = ks[i]
  x
end.transpose

# write new file
CSV.open("myfile.csv", "w") do |csv|
  k.each do |row|
    csv << row
  end
end