Замена текста в одном столбце CSV с помощью FasterCSV - PullRequest
0 голосов
/ 13 декабря 2010

Будучи относительно новым для 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

Единственная проблема заключается в том, что есть преобразование заголовка, где я не ожидаю этого.Если заголовок выбранного столбца - «MyCol» до замены столбцов в таблице csv, то впоследствии это «mycol» (см. Комментарии в коде).Почему это происходит?И как этого избежать?Спасибо.

Ответы [ 2 ]

4 голосов
/ 14 декабря 2010

Есть несколько вещей, которые вы можете изменить в строке инициализации, которые помогут. Изменения:

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

до:

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

Я использую CSV, который является только FasterCSV и является частью Ruby 1.9. Это создаст файл CSV в текущем каталоге с именем «temp.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
3 голосов
/ 17 декабря 2010

Можно манипулировать нужным столбцом непосредственно в объекте 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
...