2010-12-13 55 views
0

對於Ruby來說相對較新,我試圖弄清楚如何使用FasterCSV執行以下操作:打開一個CSV文件,在其列表中選擇一個列,在此列中只替換全部字符串x與y的出現,將新文件寫出到STDOUT。 下面的代碼幾乎工作:使用FasterCSV替換一個CSV列中的文本

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

在初始化行中有幾件事可以改變,這將有所幫助。更改:

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 
+0

謝謝Greg。當你編寫有用的東西時,直接操縱選擇列而不是構建新列,然後嘗試用新列替換現有列(請參見下面的代碼)。 – Stefan 2010-12-17 08:12:19

3

它是可以操縱所需列直接在FasterCSV對象中,而不是創建新列,然後嘗試用新的列替換舊列。