使用FasterCSV替换一个CSV列中的文本

作为相对较新的Ruby,我试图弄清楚如何使用FasterCSV执行以下操作:打开CSV文件,通过其标题选择一列,在此列中仅用y替换所有出现的字符串x,写出新文件到STDOUT。 以下代码几乎可以工作:

filename = ARGV[0] csv = FCSV.read(filename, :headers => true, :header_converters => :symbol, :return_headers => true, :encoding => 'u') mycol = csv[:mycol] # construct a mycol_new by iterating over mycol and doing some string replacement puts csv[:mycol][0] # produces "MyCol" as expected puts mycol_new[0] # produces "MyCol" as expected csv[:mycol] = mycol_new puts csv[:mycol][0] # produces "mycol" while "MyCol" is expected csv.each do |r| puts r.to_csv(:force_quotes => true) end 

唯一的问题是有一个标题转换,我不指望它。 如果在替换csv表中的列之前所选列的标题是“MyCol”,则之后是“mycol”(请参阅​​代码中的注释)。 为什么会这样? 以及如何避免它? 谢谢。

您可以在初始化行中更改一些有用的内容。 更改:

 csv = FCSV.read(filename, :headers => true, :return_headers => true, :encoding => 'u') 

至:

 csv = FCSV.read(filename, :headers => true, :encoding => 'u') 

我正在使用CSV,这是FasterCSV,它只是Ruby 1.9的一部分。 这将在当前目录中创建一个名为“temp.csv”的CSV文件,其中包含已修改的“FName”字段:

 require 'csv' data = "ID,FName,LName\n1,mickey,mouse\n2,minnie,mouse\n3,donald,duck\n" # read and parse the data csv_in = CSV.new(data, :headers => true) # open the temp file CSV.open('./temp.csv', 'w') do |csv_out| # output the headers embedded in the object, then rewind to the start of the list csv_out << csv_in.first.headers csv_in.rewind # loop over the rows csv_in.each do |row| # munge the first name if (row['FName']['mi']) row['FName'] = row['FName'][1 .. -1] << '-' << row['FName'][0] << 'ay' end # output the record csv_out << row.fields end end 

输出如下:

 ID,FName,LName 1,ickey-may,mouse 2,innie-may,mouse 3,donald,duck 

可以直接在FasterCSV对象中操作所需的列,而不是创建新列,然后尝试用新列替换旧列。

 csv = FCSV.read(filename, :headers => true, :header_converters => :symbol, :return_headers => true, :encoding => 'u') mycol = csv[:my_col] mycol.each do |row| row.gsub!(/\s*;\s*/,"///") unless row.nil? # or any other substitution csv.each do |r| puts r.to_csv(:force_quotes => true) end