Ruby 使用FasterCSV替换一个CSV列中的文本
由于对Ruby比较陌生,我正试图找出如何使用FasterCSV执行以下操作: 打开一个CSV文件,按其标题选择一列,在该列中,仅将所有出现的字符串x替换为y,将新文件写入标准输出。 以下代码几乎可以工作:Ruby 使用FasterCSV替换一个CSV列中的文本,ruby,fastercsv,Ruby,Fastercsv,由于对Ruby比较陌生,我正试图找出如何使用FasterCSV执行以下操作: 打开一个CSV文件,按其标题选择一列,在该列中,仅将所有出现的字符串x替换为y,将新文件写入标准输出。 以下代码几乎可以工作: filename = ARGV[0] csv = FCSV.read(filename, :headers => true, :header_converters => :symbol, :return_headers => true, :encoding => 'u'
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表中的列之前为“mycl”,则之后为“mycl”(请参见代码中的注释)。为什么会发生这种情况?如何避免呢?谢谢。您可以在初始化行中更改一些有帮助的内容。更改:
csv = FCSV.read(filename, :headers => true, :return_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
可以直接在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
谢谢你,格雷格。在编写时,有帮助的是直接操作所选列,而不是构建一个新列,然后尝试用新列替换现有列(请参见下面的代码)。
ID,FName,LName
1,ickey-may,mouse
2,innie-may,mouse
3,donald,duck
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