如何使用Ruby映射和编辑CSV文件

时间:2015-10-24 18:27:37

标签: ruby csv

有没有办法在Ruby中使用CSV.open("file.csv", "a+") 方法编辑CSV文件?我知道我可以使用以下方式打开文件:

foreach

并向其添加内容,但我必须编辑一些特定的行。

std::vector<ObjectPtr<T>> objects_; 方法仅对阅读文件有用(如果我错了,请更正我)。

我检查了Ruby CSV documentation,但我找不到任何有用的信息。

我的CSV文件少于1500行,所以我不介意阅读所有行。

3 个答案:

答案 0 :(得分:3)

使用each.with_index()的另一个答案:

rows_array = CSV.read('sample.csv')

desired_indices = [3, 4, 5].sort # these are rows you would like to modify
rows_array.each.with_index(desired_indices[0]) do |row, index| 
  if desired_indices.include?(index)

    # modify over here
    rows_array[index][target_column] = 'modification'

  end
end

# now update the file
CSV.open('sample3.csv', 'wb') { |csv| rows_array.each{|row| csv << row}}

答案 1 :(得分:1)

这是我写的一个小脚本,作为一个例子,说明如何读取CSV数据,对数据执行某些操作,然后将编辑后的文本写入新文件:

read_write_csv.rb:

#!/usr/bin/env ruby
require 'csv'

src_dir = "/home/user/Desktop/csvfile/FL_insurance_sample.csv"
dst_dir = "/home/user/Desktop/csvfile/FL_insurance_sample_out.csv"
puts " Reading data from  : #{src_dir}"
puts " Writing data to    : #{dst_dir}"
#create a new file 
csv_out = File.open(dst_dir, 'wb')
#read from existing file
CSV.foreach(src_dir , :headers => false) do |row|

  #then you can do this 
  # newrow = row.each_with_index { |rowcontent , row_num| puts "#     {rowcontent} #{row_num}" }

  # OR array to hash .. just saying .. maybe hash of arrays.. 
  #h = Hash[*row]
  #csv_out << h

  # OR use map  
  #newrow = row.map(&:capitalize)
  #csv_out << h

  #OR use each  ... Add and end 
  #newrow.each do |k,v| puts "#{k} is #{v}"

  #Lastly,  write back the edited , regexed data ..etc to an out file.
  #csv_out << newrow

end

# close the file 
csv_out.close

输出文件包含所需的数据:

USER@USER-SVE1411EGXB:~/Desktop/csvfile$ ls
FL_insurance_sample.csv  FL_insurance_sample_out.csv  read_write_csv.rb

输入文件数据如下所示:

policyID,statecode,county,eq_site_limit,hu_site_limit,fl_site_limit,fr_site_limit,tiv_2011,tiv_2012,eq_site_deductible,hu_site_deductible,fl_site_deductible,fr_site_deductible,point_latitude,point_longitude,line,construction,point_granularity
119736,FL,CLAY COUNTY,498960,498960,498960,498960,498960,792148.9,0,9979.2,0,0,30.102261,-81.711777,Residential,Masonry,1
448094,FL,CLAY COUNTY,1322376.3,1322376.3,1322376.3,1322376.3,1322376.3,1438163.57,0,0,0,0,30.063936,-81.707664,Residential,Masonry,3
206893,FL,CLAY COUNTY,190724.4,190724.4,190724.4,190724.4,190724.4,192476.78,0,0,0,0,30.089579,-81.700455,Residential,Wood,1
333743,FL,CLAY COUNTY,0,79520.76,0,0,79520.76,86854.48,0,0,0,0,30.063236,-81.707703,Residential,Wood,3
172534,FL,CLAY COUNTY,0,254281.5,0,254281.5,254281.5,246144.49,0,0,0,0,30.060614,-81.702675,Residential,Wood,1

答案 2 :(得分:1)

  

有没有办法在Ruby中使用map方法编辑CSV文件?

是:

rows = CSV.open('sample.csv')
rows_array = rows.to_a

rows_array = CSV.read('sample.csv')
desired_indices = [3, 4, 5] # these are rows you would like to modify

edited_rows = rows_array.each_with_index.map do |row, index| 
  if desired_indices.include?(index)

    # simply return the row
    #   or modify over here
    row[3] = 'shiva'

    # store index in each edited rows to keep track of the rows
    [index, row]

  end
end.compact

# update the main row_array with updated data
edited_rows.each{|row| rows_array[row[0]] = row[1]}

# now update the file
CSV.open('sample2.csv', 'wb') { |csv| rows_array.each{|row| csv << row}}

这有点乱。是不是?我建议您使用each_with_index而不是map来执行此操作。看到我的另一个答案