2011-04-18 52 views
4

我有一個Python腳本,修改一個CSV文件的文件名添加爲最後一欄添加文件名爲CSV的最後一列文件

import sys 
import glob 

for filename in glob.glob(sys.argv[1]): 
    file = open(filename) 
    data = [line.rstrip() + "," + filename for line in file] 
    file.close() 

    file = open(filename, "w") 
    file.write("\n".join(data)) 
    file.close() 

不幸的是,它也增加了文件名的頭(第一)文件的一行。我想將字符串「ID」添加到標題中。有人可以建議我怎麼做到這一點?

回答

1

你可以試試:

data = [file.readline().rstrip() + ",id"] 
data += [line.rstrip() + "," + filename for line in file] 
1

請使用Python自帶的CSV module

import csv 
import sys 

def process_file(filename): 
    # Read the contents of the file into a list of lines. 
    f = open(filename, 'r') 
    contents = f.readlines() 
    f.close() 

    # Use a CSV reader to parse the contents. 
    reader = csv.reader(contents) 

    # Open the output and create a CSV writer for it. 
    f = open(filename, 'wb') 
    writer = csv.writer(f) 

    # Process the header. 
    header = reader.next() 
    header.append('ID') 
    writer.writerow(header) 

    # Process each row of the body. 
    for row in reader: 
     row.append(filename) 
     writer.writerow(row) 

    # Close the file and we're done. 
    f.close() 

# Run the function on all command-line arguments. Note that this does no 
# checking for things such as file existence or permissions. 
map(process_file, sys.argv[1:]) 

可以按如下方式運行此:

[email protected]:~$ python csv_add_filename.py file1.csv file2.csv 
1

你可以試着改變你的代碼,但使用csv module建議。這應該給你結果你想:

import sys 
import glob 
import csv 

filename = glob.glob(sys.argv[1])[0] 
yourfile = csv.reader(open(filename, 'rw')) 

csv_output=[] 

for row in yourfile: 
    if len(csv_output) != 0:  # skip the header 
     row.append(filename) 
    csv_output.append(row) 

yourfile = csv.writer(open(filename,'w'),delimiter=',') 
yourfile.writerows(csv_output) 
5

這裏是您目前的代碼一些小筆記:

  • 這是一個糟糕的主意,用file作爲變量名,因爲這陰影內置類型。
  • 您可以使用with語法自動關閉文件對象。
  • 難道你不想在標題行中添加一個額外的列,名爲Filename,而不是僅僅省略第一行中的一列?
  • 如果你的文件名在它們中有逗號(或者不太可能是換行符),你需要確保文件名被引用 - 只是追加它不會。

最後的考慮將傾向於使用csv模塊來代替,它將處理引用和不引用。例如,你可以嘗試像下面的代碼:

import glob 
import csv 
import sys 

for filename in glob.glob(sys.argv[1]): 
    data = [] 
    with open(filename) as finput: 
     for i, row in enumerate(csv.reader(finput)): 
      to_append = "Filename" if i == 0 else filename 
      data.append(row+[to_append]) 
    with open(filename,'wb') as foutput: 
     writer = csv.writer(foutput) 
     for row in data: 
      writer.writerow(row) 

可以從輸入文件略有不同引述的數據,所以你可能要與報價選項發揮csv.readercsv.writer描述in the documentation for the csv module

作爲一個進一步的觀點,你可能有充分的理由將glob作爲參數而不僅僅是命令行上的文件,但這有點令人驚訝 - 你必須將你的腳本作爲./whatever.py '*.csv'而不是僅僅調用./whatever.py *.csv。相反,你可以這樣做:

for filename in sys.argv[1:]: 

...並讓shell在腳本知道任何事情之前展開您的glob。

最後一件事 - 當前採用的方法有點危險,因爲如果寫回相同的文件名時出現任何錯誤,您將丟失數據。避免這種情況的標準方法是寫入臨時文件,如果成功,則將臨時文件重命名爲原始文件。所以,你可能重寫整個事情:

import csv 
import sys 
import tempfile 
import shutil 

for filename in sys.argv[1:]: 
    tmp = tempfile.NamedTemporaryFile(delete=False) 
    with open(filename) as finput: 
     with open(tmp.name,'wb') as ftmp: 
      writer = csv.writer(ftmp) 
      for i, row in enumerate(csv.reader(finput)): 
       to_append = "Filename" if i == 0 else filename 
       writer.writerow(row+[to_append]) 
    shutil.move(tmp.name,filename) 
+1

這是一個很好的例子,由於做。 – Richard 2011-09-27 12:02:18

+1

極好的例子。感謝您使用tempfile的建議! – aravenel 2012-06-15 18:31:50

1

可以使用的FileInput就地編輯

import sys 
import glob 
import fileinput 

for filename in glob.glob(sys.argv[1]): 
    for line in fileinput.FileInput(filename,inplace=1) : 
     if fileinput.lineno()==1: 
      print line.rstrip() + " ID" 
     else 
      print line.rstrip() + "," + filename 
相關問題