【问题标题】:Replacing text in one CSV column using FasterCSV使用 FasterCSV 替换一个 CSV 列中的文本
【发布时间】:2010-12-13 16:16:06
【问题描述】:

对 Ruby 来说相对较新,我试图弄清楚如何使用 FasterCSV 执行以下操作: 打开一个 CSV 文件,通过其标题选择一列,在该列中仅将所有出现的字符串 x 替换为 y,将新文件写入 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”(参见代码中的 cmets)。为什么会这样?以及如何避免?谢谢。

【问题讨论】:

    标签: ruby fastercsv


    【解决方案1】:

    您可以在初始化行中进行一些更改,这会有所帮助。变化:

    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
    

    【讨论】:

    • 谢谢格雷格。在您编写时,有帮助的是直接操作选择的列,而不是构建一个新列,然后尝试用新列替换现有列(参见下面的代码)。
    【解决方案2】:

    可以直接在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多