2017-02-20 56 views
2

我已經嘗試了劇本的多次反覆,但現在又回到一個空白的記事本+Python的 - 將文件移動到包含文件名

盯着的一部分文件夾我有形式6K文件夾:

Reading Festival 1999 
Reading Festival 2000 
Reading Festival 2001 
Leeds Festival 1999 
Leeds Festival 2000 
Leeds Festival 2001 
Download Festival 2005 
Download Festival 2006 
... 

在同一個文件夾我的文件有一個長長的清單形式

Artist at {Festival Name} by Photographer - UID 

哪裏Artist是誰的人在節日出場,Photographer是人WH Ø把它和UID是一個唯一的ID

我的問題是我怎麼會去通過文件夾循環,對於每一個,看文件名中包含文件夾的名稱,如果這樣做,將文件移動那裏。

import os 
rootdir = 'C:\Users\Alan\Desktop\VF' 

for subdir, dirs, files in os.walk(rootdir): 
    for d in dirs: 
     for file in files: 
      the_file = os.path.join(subdir, file) 
      if d in the_file: 
       new_loc = subdir + '\\' + d + '\\' + file 
       os.rename(the_file, new_loc) 

我有這樣的代碼,我相信應該的工作,但我擔心的是,它會通過已經夾內的所有圖像讀取。我將如何避免這種情況?

+0

我是否正確,所有的文件和文件夾都在同一級別?我想知道是否需要使用os.walk() - 它遍歷樹。你需要嗎? –

+1

不 - 我意識到這一點,所以看着listdir ....感謝推動 – pee2pee

回答

1

由於您的文件和文件夾都在同一水平上,你不需要用os.walk()遍歷目錄樹。 os.listdir()會做,而不是像你在評論中指出的那樣。一個解決辦法是用os.listdir()得到的目錄和文件列表並在您之前也做了同樣的方式找到new_loc名稱,使用in代替正則表達式。

folders = [d for d in os.listdir('.') if os.path.isdir(d)] 
files = [f for f in os.listdir('.') if os.path.isfile(f)] 
for d in folders: 
    for f in files: 
     if d in f: 
      new_loc = subdir + '\\' + d + '\\' + file 
      os.rename(the_file, new_loc) 

這裏的邏輯與您的邏輯大致相同,只是以不同的方式獲取您的目錄和文件!

+1

謝謝 - 這符合我的想法。 walk和listdir之間的資源利用率是多少? – pee2pee

+1

@ pee2pee我不是100%肯定的,但我會認爲walk會佔用更多的資源,因爲它遍歷一棵樹 - 尤其是如果你的目錄樹很深的話 –

+0

你可以修改這個只給我們一個listdir一次 - make a listdir列表,然後使用'isdir'和'isfile'將它分成兩個列表 –

0

如果我理解正確,你有一個頂級目錄,當你開始這個過程中,一切都在它要麼是對應於節日或文件的空目錄中移動。我認爲您根本不需要使用os.walk,只需遍歷頂級目錄中的內容即可。

我假設你定義了兩個功能:

  • def extract_festival(fname)返回「讀書節1999」或任何恰當
  • def move_file(fname, festival)將文件移動到的地方。你需要檢查節日的目錄是否存在,如果不是,做任何適當的事情。

然後你只需要像:

for fname in os.listdir(rootdir): 
    if os.path.isfile(os.path.join(rootdir, fname)): # double check that listdir doesn't give you the full path 
     festival = extract_festival(fname) 
     move_file(fname, festival) 
    # otherwise, it's a directory, so leave it alone 

我認爲extract_festival是一個正則表達式。像這樣將處理「快樂」的情況:

def extract_festival(fname): 
    match = re.match(".+at(.+[0-9]{4}) by.+") 
    return match.group(1) 

如果不匹配(例如,如果你有一個壞的文件名),matchNone,你就必須決定做什麼。在這種情況下,match.group將引發錯誤。我可能會做一些像return match.group(1) if match is not None else match之類的東西,然後在for循環中檢查None(可能打印文件名以便我可以用手修復它)。

+0

樂隊的名字可能有「通過」在....我經歷了正則表達式的可能性,但由於每個元素名稱他們自己,沒有藝術家/活動/攝影師的絕對開始/結束 – pee2pee

+0

是的,如果我正確地思考貪婪的話,你會匹配'指導聲音'中的'by'。你必須對由第一個正則表達式引出的組進行第二次檢查,以確保它沒有另一個'by' - 我認爲只要沒有' '以節日的名義。然後你卡住了。 另一種方法是通過遍歷'rootdir'一次,然後檢查子字符串包含來組裝一個節點名稱列表。這可能很小,不會太糟糕。 – hoyland

相關問題