8

我正在从数据库查询中检索大量结果哈希并将它们写入 csv 文件。下面的代码块获取结果并创建 CSV。使用该quote_char:选项,它将用我需要正确创建制表符分隔文件的 NULL 字符替换引号。

但是,当它们被加载到目的地时,NULL 字符会被转换为“”,所以我想删除它们。如果我遗漏quote_char:每个字段都是双引号,这会导致相同的结果。

如何删除 NULL 字符?

begin
    CSV.open("#{file_path}"'file.tab', "wb", Options = {col_sep: "\t", quote_char: "\0"}) do |csv|
        csv << ["Key","channel"]           
        series_1_results.each_hash do |series_1|
         csv << ["#{series_1['key']}","#{series_1['channel']}"]
        end
    end
end
4

4 回答 4

4

正如csv 文档中所述,您必须设置quote_char为某个字符,并且该字符将始终用于引用空字段。

在这种情况下,似乎唯一的解决方案是quote_chars从创建的 csv 文件中删除 used 。你可以这样做:

quotedFile = File.read("#{file_path}"'file.tab')
unquotedFile = quotedFile.gsub("\0", "")
File.open("#{file_path}"'unquoted_file.tab',"w") { |file| file.puts replace }

我在这里假设 NULL 是唯一的转义字段。如果不是这种情况,请使用 defaultquote_char: '"'并且gsub(',"",', '')应该处理几乎所有可能的包含特殊字符的字段的情况。

但正如您注意到的那样,您的查询结果很大,您自己准备 csv 文件并避免两次处理输出可能更实际。你可以简单地写:

File.open("#{file_path}"'unquoted_file.tab',"w") do |file|
    csv.puts ["Key","channel"]     
    series_1_results.each_hash do |series_1|
        csv.puts ["#{series_1['key']},#{series_1['channel']}"]
    end
end

再一次,您可能需要处理带有特殊字符的字段。

于 2013-05-19T18:40:47.127 回答
3

Ruby CSV文档force_quotes: false中,选项中的设置似乎有效。

CSV.open("#{file_path}"'file.tab', "wb", { col_sep: "\t", force_quotes: false }) do |csv|

以上就是诀窍。我建议不要设置quote_char为,\0因为这不能按预期工作。

不过有一点需要注意。如果该字段为空字符串""- 它将强制将quote_char其打印到 CSV 中。但奇怪的是,nil价值没有。我建议,如果您完全期望数据中有空字符串,那么nil在写入 CSV 时以某种方式将它们转换为(可能使用 ActiveSupportpresence方法或类似方法)。

于 2013-05-19T19:53:02.583 回答
1

首先,制表符分隔的文件是“TSV”,而逗号分隔的文件是“CSV”。

任何时候在字段中可能出现字段分隔符时,都需要在字段周围加上引号。

例如,您将如何将此字符串嵌入到制表符分隔的文件中?

Foo\tbar

\t是嵌入式的表示Tab

写入包含逗号的字段的 CSV 文件时会出现同样的问题。该字段必须用双引号括起来以分隔该字段本身。

于 2013-05-10T07:28:14.890 回答
1

如果您的输入包含任何需要转义的数据(例如列分隔符或引号字符),那么您确实需要引用您的数据。否则以后无法正确解析。

CSV.open('test.csv', 'wb', col_sep: "\t") do |csv|
  csv << ["test", "'test'", '"test"', nil, "test\ttest"]
end

puts open('test.csv').read
#test    'test'  """test"""              "test   test"

CSV 类不会引用任何不必要的内容(如上所示)。所以我不确定你为什么说你所有的领域都被引用了。它可能以某种方式force_quotes在某处被设置为 true。

如果您绝对确定您的数据永远不会包含\tor ",那么默认quote_char( ") 应该可以正常工作。否则,如果您想避免引用任何内容,则需要选择另一个您绝对确定不会出现在数据中的引号字符。

CSV.open('test.csv', 'wb', col_sep: "\t", quote_char: "|") do |csv|
  csv << ["test", "'test'", nil, '"test"']
end

puts open('test.csv').read
#test    'test'          "test"
于 2013-05-17T06:30:53.513 回答