2013-05-10 19 views
8

データベースクエリの結果の大きなハッシュを取得し、それらをcsvファイルに書き出します。下のコードブロックは結果を受け取り、CSVを作成します。 quote_char:オプションでは、タブ区切りファイルを正しく作成するために必要なNULL文字で引用符を置き換えます。Ruby CSV.openは引用符とヌル文字を削除する必要があります

しかし、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 
+0

出力に必要なものをもっと明確にするには、名前を付けて保存...メニューの 'Windows Formatted Text.txt'で提供されている形式と一致する必要があります。これは、ファイルに引用符がないタブ区切り形式です。 – analyticsPierce

答えて

3

それがに記載されたようcsv documentationあなたには、いくつかの文字に設定quote_charに持っており、この文字は常に引用空のフィールドに使用されます。

この場合、唯一の解決策は、作成されたcsvファイルからquote_charsを削除することだと思われます。私はNULLのが唯一のエスケープフィールドであることを前提とし、ここで

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

:あなたはこのようにそれを行うことができます。そうでない場合は、デフォルトのquote_char: '"'gsub(',"",', '')を使用してください。を処理すると、ほぼの特殊文字を含むフィールドのすべての場合があります。

しかし、クエリの結果が大きければ、csvファイルを自分で準備し、出力を2回処理しないほうが現実的かもしれません。

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 

もう一度、特殊文字を含むフィールドを処理する必要があります。

1

まず、タブ区切りファイルは "TSV"とカンマ区切りのファイル "CSV"です。

フィールド内にフィールド区切り文字が現れる可能性がある場合はいつでも、フィールドを囲む引用符が必要です。

たとえば、この文字列をタブ区切りファイルにどのように埋め込むのですか?

Foo\tbar 

\tは埋め込みタブの表現です。

カンマを含むフィールドを含むCSVファイルを書き込むときにも同じ問題が発生します。フィールド自体を区切るには、フィールドを二重引用符で囲む必要があります。

+0

データにタブ文字のインスタンスがありません。私はあなたが正しいので、いくつかのテキスト引用符を持つフィールドをラップすると大丈夫ですそれを持っていることが良いです。しかし、どうすればNULLフィールドを引用符なしで残すことができますか? quote_charを削除すると、すべてのフィールドに引用符が付きます。何を指示してるんですか? – analyticsPierce

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はどこかに真実になっているかもしれません。

あなたは絶対確実あなたのデータは\tまたは"が含まれることはありませんしている場合は、デフォルト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" 
3

Ruby CSVから、オプションにforce_quotes: falseを設定すると機能するようです。

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

上記はトリックです。期待どおりに動作しないので、quote_char\0に設定することをお勧めします。

ただし、注意すべき点が1つあります。フィールドが空の文字列""である場合、quote_charがCSVに印刷されます。しかし、不思議なことにnil値はありません。私は、データ内の空の文字列を期待している場合は、CSVに書き込むときに何らかの形でnilに変換することをお勧めします(多分ActiveSupport presenceメソッドなどを使用)。

関連する問題