2015-05-20 30 views
0

我正在嘗試編寫一個ruby腳本,它將讀取CSV文件並將信息添加到某些單元格(例如添加一個文件路徑)。我可以打開並改變文本,但是在回寫到CSV時沒有重寫所有內容。這是我到目前爲止的例子:更改CSV文件中的信息

CSV.foreach(path) { |row| 
    text = row[0].to_s 
    new_text = "test:#{text}" 
} 

我想該塊,然後將寫new_text迴文件相同的參考單元(row)中添加一些東西。我必須找到寫入文件的唯一方法是

CSV.open(path, "wb") { |row| 
    row << new_text 
} 

但我認爲這是不好的做法,因爲你在文件塊內已經重新打開該文件。有沒有更好的方法可以做到這一點?

EX:我有一個CSV文件,看起來像:

file,destination 
test.txt,A101 

,並需要它是:

file,destination 
path/test.txt,id:A101 

希望是有道理的。提前致謝!

回答

1

根據文件的大小,可以考慮將文件內容加載到本地變量中,然後操作它,覆蓋原始文件。

lines = CSV.read(path) 

File.open(path, "wb") do |file| 
    lines.each do |line| 
    text = line[0].to_s 
    line[0] = "test:#{text}" # Replace this with your editing logic 
    file.write CSV.generate_line(line) 
    end 
end 

或者,如果該文件是大,可以在每次修改行寫沿途一個新的文件,然後在年底更換新的舊文件。

+0

我曾經想過要做那樣的事情,但並沒有想過''File'over'CSV'。我想這會讓我非常感謝你的幫助! – Luminusss

0

鑑於您似乎沒有采用CSV功能,我建議使用Ruby的「就地」選項變量$-i

我使用的一些統計軟件只需要數據,並且不能處理標題行。這是我寫回來的一段腳本(看起來像是)將第一行從命令行上指定的一個或多個數據文件中剝離出來。

#! /usr/bin/env ruby -w 
# 
# User supplies the name of one or more files to be "stripped" 
# on the command-line. 
# 
# This script ignores the first line of each file. 
# Subsequent lines of the file are copied to the new version. 
# 
# The operation saves each original input file with a suffix of 
# ".orig" and then operates in-place on the specified files. 

$-i = ".orig" # specify backup suffix 

oldfilename = "" 

ARGF.each do |line| 
    if ARGF.filename == oldfilename # If it's an old file 
    puts line      # copy lines through. 
    else        # If it's a new file remember it 
    oldfilename = ARGF.filename  # but don't copy the first line. 
    end 
end 

顯然,你會想在puts line直通改變任何編輯操作要執行。

我喜歡這個解決方案,因爲即使你搞砸了,你仍然保留原始文件作爲其原始名稱.orig(或任何後綴,你選擇)追加。