2017-02-16 13 views
0

を追加します。Parse a CSV file, update a field, then saveアップデートは、私はこの質問に似た何かをしようとしています、インプレースCSVラインにルビー

基本的に私は、各行が異なるを表し、各行は、IPアドレスのカンマ区切りリストを持つCSVを持っていますIPグループ。私は、このCSVを、各行ごとに各IPで動作する関数に渡します。その後、ステータスとタイムスタンプをラインに追加したいと思います。上記の解決策では、2番目のファイルを作成する必要があります。追加ファイルを作成せずにこれを行う方法はありますか?各行に追加するだけです。

CSV.open('csv_with_ips.csv', 'r+').each do |row| 
    <do some stuff> 
    row << 'SCANNED' 
    row << Time.now 
end 

答えて

2

あなたはは、新しいファイルを作成するを持っていないが、良い習慣は、あなたがしなければならないと言います。

長い行の行を更新するには、次の行とそれ以降の行を上書きする必要があります。ファイル全体を処理する前にコードがクラッシュした場合、コンテンツは破損します。

また、ファイル全体をメモリに読み込まなければならないことを意味します。コードの拡張がうまくいかないため、これはお勧めできません。それをメモリに読み込まないと、あなたが書いている行は、読み込みたい次の行にぶつかり、それを壊します。データの

安全な処理はこのような何かを行くだろう:

File.open('output.csv', 'w') do |fo| 
    File.foreach('input.csv') do |li| 
    # modify the input line "li" 
    fo.puts(li) 
    end 
end 

File.mv('input.csv', 'input.csv.bak') 
File.mv('output.csv', 'input.csv') 

しかし、もちろん、あなたがルビーが付属していますCSV classを利用して、重い物を持ち上げるを扱うようにしたいと思います。 CSVファイル形式は人々の思考ほど単純ではなく、データを混乱させるのは簡単ですので、CSVクラスの実装を利用してください。

+0

入力されたCSVファイルの内容がメモリに収まりきらないほど小さければ、各行を処理して配列に格納し、一度にすべて同じ名前のファイルにダンプすることもできます。 –

+0

これはうまくいくと思われますが、メモリを超えるファイルが読み取られるまで動作します。私が働いている環境では、ファイルはGBの10分の1によく見えますので、それらをスラッピングすると処理速度が低下しますが、行単位のIOは遅くなりません。それが良い考えではない理由については、いくつかのメトリクスについてはhttp://stackoverflow.com/q/25189262/128421を参照してください。それ以外に、書き込み中にコードがクラッシュすると、データファイルが破損します。生産データの保存は非常に重要です。 –

+0

合意。参照リンクをありがとう。 –

関連する問題