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

问题描述 投票:0回答:2

我有两个不同标题的csv。

让我们说csv 1有一个,两个,三个,四个标题,我想创建一个带有标题五,六,七,八的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
ruby csv
2个回答
2
投票

人们往往过于复杂化。您根本不需要任何CSV处理来替换标头。

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

让我们替换标题并将其他所有内容都流动起来。

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

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
© www.soinside.com 2019 - 2024. All rights reserved.