0

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」になります (コード内のコメントを参照)。なぜこれが起こるのですか?そして、それを回避する方法は?ありがとう。

4

2 に答える 2

4

初期化行で変更できることがいくつかあります。変化する:

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

に:

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

Ruby 1.9の一部であるFasterCSVのみであるCSVを使用しています。これにより、現在のディレクトリに「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
于 2010-12-14T06:57:19.417 に答える
3

新しい列を作成してから古い列を新しい列に置き換えようとする代わりに、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
于 2010-12-17T08:19:40.727 に答える