2013-02-02 50 views
2

編輯重命名文件名的一部分:見底部的我最終解決批從查找文件

我有〜12700文本文件的目錄。

他們有這樣的名字:

1 - 回覆/報告Novenator公開徵求埋葬 - 通過Lizbett上週四,9月10日2009.txt

如果每個文件的領先的數字遞增(例如目錄中的最後一個文件以「12,700 - 」開頭)。

不幸的是,這些文件沒有被排序,我需要它們。幸運的是,我有一個單獨的CSV文件,其中ID號碼被映射,例如1在上面的例子確實應該25(因爲有收到24級的消息),和2應該真正是8位,並且3應爲1,等等,例如:

OLD_FILEID TIMESORT_FILEID 
21  0 
23  1 
24  2 
25  3 

我不除了需要與相關值交換的這個單獨的前導號碼之外,還需要更改文件標題中的任何內容。在我的腦海中,這樣做的方式是打開文件名,檢查短劃線之前出現的數字,在CSV中查找它們,將它們替換爲關聯的值,然後用調整後的標題保存文件,然後轉到到下一個文件。

什麼是最好的方式去做這樣的事情?我是一個蟒蛇新手,但玩了足夠的感覺舒服遵循大多數方向或建議。謝謝:)

E:遵照下面的說明是盡我所能我這樣做,這是不行的,但我不知道爲什麼:

import os 
import csv 
import sys 

#open and store the csv file 
with open('timesortmap.csv','rb') as csvfile: 
timeReader = csv.reader(csvfile, delimiter = ',', quotechar='"') 

#get the list of files 
for filename in os.listdir('DiggOutput-TIMESORT/'): 
oldID = filename.split(' - ')[0] 
newFilename = filename.replace(oldID, timeReader[oldID],1) 
os.rename(oldID, newFilename) 

我得到的錯誤是:

TypeError: '_csv.reader' object is not subscriptable 

我不使用DictReader,但那是因爲當我使用csv.reader和打印的行,它看起來像這樣:

['12740', '12738'] 
['12742', '12739'] 
['12738', '12740'] 
['12737', '12741'] 
['12739', '12742'] 

當我使用DictReader它看起來像這樣:

{'FILEID-TS': '12738', 'FILEID-OLD': '12740'} 
{'FILEID-TS': '12739', 'FILEID-OLD': '12742'} 
{'FILEID-TS': '12740', 'FILEID-OLD': '12738'} 
{'FILEID-TS': '12741', 'FILEID-OLD': '12737'} 
{'FILEID-TS': '12742', 'FILEID-OLD': '12739'} 

我在終端得到這個錯誤:

File "TimeSorter.py", line 16, in <module> 
newFilename = filename.replace(oldID, timeReader[oldID],1) 
AttributeError: DictReader instance has no attribute '__getitem__' 
+0

實際數據的一些例子將是很好的,以及預期的結果... –

+0

當然可以。文本文件:http://cl.ly/192b2H0l0f1Y。完整CSV:http://cl.ly/3m2v2e072E2U。帶有文件ids的地圖:http://cl.ly/112n3A3H1Z3O。 – peteyreplies

回答

1

這確實應該是很簡單的用Python做的只是用csvos模塊。

Python有一個內置的dictionary type,叫做dict,可以用來在處理時存儲內存中csv文件的內容。基本上,您需要使用csv模塊讀取csv文件,並將每個條目轉換爲字典條目,可能使用OLD_FILEID字段作爲關鍵字,TIMESORT_FILEID作爲值。

然後,您可以使用os.listdir()來獲取文件列表,並使用循環來依次獲取每個文件名。 (如果您需要過濾文件名列表以排除某些文件,請查看glob模塊)。裏面你的循環,你只需要提取與文件相關聯的編號,可以使用這樣的事情要做:

file_number = filename.split(' - ')[0] 

然後調用os.rename()傳遞舊文件名和新的文件名。新的文件名可以使用類似發現:

new_filename = filename.replace(file_number, file_mapping[file_number], 1) 

哪裏file_mapping是從CSV文件創建的字典。這將用您的映射文件中的編號替換第一次出現的file_number

編輯

由於TheodrosZelleke指出的,是覆蓋由字面下面就是我上面佈局的現有文件的潛力。一些可能的策略:

  1. 使用os.rename()移動文件的重命名版本到不同的目錄(如當前目錄,或者甚至更好,一個臨時目錄中創建使用tempfile.mkdtemp()的子目錄,一旦所有的文件已。
  2. 爲新文件名添加擴展名,例如.tmp,假設選擇的擴展名不會導致其他衝突,一旦完成所有的重命名,使用第二個循環來重命名文件以排除.tmp擴展名。
+0

@TheodrosZelleke:你說得很好。我不確定它是否值得倒票,但我已經編輯了答案來解釋這一點,因爲命名衝突的可能性相當大,給出了示例數據。 – ig0774

+0

我收回了投票權。我理解反對票也是一種表示答案需要改進的手段(這是一種錯誤的解釋?)。當答案得到改善時,我總是收回票數。我很少投票,但在這種情況下,我認爲OP有丟失數據的真實危險......從個人經驗來看,我知道發生的速度有多快;) –

+0

@ ig0774我試着盡我所能理解,要將相當好的東西加載成對,它似乎在此後突破。如果它是一個快速修復,任何額外的幫助將不勝感激。 – peteyreplies

0

這裏是我結束了與朋友工作了,應該有人發現和尋找這樣的:

import os 
import csv 
import sys 

IDs = {} 

#open and store the csv file 
with open('timesortmap.csv','rb') as csvfile: 
     timeReader = csv.reader(csvfile, delimiter = ',', quotechar='"') 

     # build a dictionary with the associated IDs 
     for row in timeReader: 
       IDs[ row[0] ] = row[1] 

# #get the list of files 
path = 'DiggOutput-OLDID/' 
tmpPath = 'DiggOutput-TIMESORT/' 
for filename in os.listdir('DiggOutput-OLDID/'): 
    oldID = filename.split(' - ')[0] 
    newFilename = filename.replace(oldID, IDs[oldID]) 
    os.rename(path + filename, tmpPath + newFilename)