Ruby使用引号读写CSV文件

7

我希望能够读取CSV中的一行数据,更新其中一个字段,并再次输出该行,且每个字段均包含在引号中。

Row Example Input => "Joe", "Blow", "joe@blow.com"
Desired Row Example Output => "Joe", "Blow", "xxxx@xxxx.xxx"

My script below outputs => Joe, Blow, xxxx@xxxx.xxx

它会丢失我想保留的双引号。

我已经尝试了各种选项,但迄今为止没有成功。有什么提示吗?

非常感谢!

require 'csv'

CSV.foreach('transactions.csv',
            :quote_char=>'"',
            :col_sep =>",", 
            :headers => true, 
            :header_converters => :symbol ) do |row| 

row[:customer_email] = 'xxxx@xxxx.xxx'

puts row

end

你想在原本没有引号的情况下添加引号吗?还是说你总是会有带引号的输入? - Justin L.
引号已经在第一位了。 - Rudi Starcevic
3个回答

11

在CSV字段中使用引号通常是不必要的,除非该字段本身包含分隔符或换行符。但您可以强制CSV文件始终使用引号。为此,您需要设置force_quotes => true

CSV.foreach('transactions.csv',
            :quote_char=>'"',
            :col_sep =>",", 
            :headers => true, 
            :force_quotes => true,
            :header_converters => :symbol ) do |row| 

:force_quotes => true 对输出结果没有影响。 - Rudi Starcevic
引号仅在写入新的CSV文件时才相关,而不是用于屏幕输出。 - Tim Pietzcker

1
您可以手动将它们添加到所有项目中。
Hash[row.map { |k,v| [k,"\"#{v}\""] }]

(由于我忘记你有哈希而不是数组,所以进行了编辑)


感觉已经接近了,但还是没有成功。这个输出看起来像“[:customer_email,“xxxx@xxxx.xxx”]”。 - Rudi Starcevic
在 puts row 之前添加 row = Hash[row.map { |k,v| [k,""#{v}""] }],然后输出将会是这样的::customer_email=>""xxxx@xxxx.xxx""。 - Rudi Starcevic
@user1064314 这是预期的,因为 puts 一个哈希将给出键的字符串文字表示(即,您在 Ruby 中键入以获取给定字符串的内容)。如果您只是 put row[:customer_email],则会看到它没有外部引号。 - Justin L.

1

感谢 Justin L.

基于您的解决方案,我最终得到了这个。

我感觉 Ruby 有更优雅的解决方案,但这个已经满足我的需求:

require 'csv'

CSV.foreach('trans.csv',
            :quote_char=>'"',
            :col_sep =>",", 
            :headers => true,
            :header_converters => :symbol ) do |row| 

row[:customer_email] = 'xxxx@xxxx.xxx'

row = Hash[row.map { |k,v| [k,"\"#{v}\""] }]

new_row = ""

row.each_with_index do | (k, v) ,i|
  new_row += v.to_s
  if i != row.length - 1
    new_row += ','
  end
end

puts new_row

end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接