2012-07-09 344 views
0

我是Python新手,需要一個將文件從同一天覆制到新文件夾的程序。將具有相同名稱的所有文件放在一個文件夾中

示例文件:

20120807_first_day_pic.jpg 
20120807_first_day_sheet.jpg 
20120807_first_day_sheet2.jpg 
20120907_second_day_pic.jpg 
20120907_second_day_sheet.jpg 
20120907_second_day_sheet2.jpg 

這是我到目前爲止,但每個文件都被一個文件夾,而不是整天。

import os, re, shutil 

tfolder = 'D:/Testing/src/' 

os.chdir(tfolder) 

re_year19xxxxxx = re.compile('(19[0-9][0-9][0-9][0-9])') 
re_year20xxxxxx = re.compile('(20[0-9][0-9][0-9][0-9])') 

re_ed = re.compile('(ED[0-9])') 
destPath = 'D:/Testing/Dest/' 

def analyse_file_name(fname): 
    filePath, coords = os.path.split(fname) #the new folders will be named according to the first 4 characters of the original file name 
    coordsFolder = coords[:53] 
    coordsFname = coords[:53] 
    coordsExt = os.path.splitext(fname) 
    year = 'year' #create variable year 
    ed = 'ed' #create variable ed to store the edition number if necessary 
    bname = fname #the original file name 
    for re_year in (re_year19xxxxxx, re_year20xxxxxx): 
     rx = re_year.search(fname) #search for regex in the file name and store it in rx 
     if rx: 
      year = rx.group(1) #if the regex is found, store the year 
      bname.replace(year, ' ') 
      res = re_ed.search(fname) 
      if res: 
       ed = res.group(1) 
       bname.replace(ed, ' ') 
     os.chdir(destPath) 
     if year is 'year': 
      fname2 = os.path.join(destPath, coordsFolder) + '\\' + coordsFname + coordsExt[1] 
     else: 
      fname2 = os.path.join(destPath, coordsFolder,year,ed) + '\\' + coordsFname + coordsExt[1] 
     print('%s -> %s' % (fname, fname2)) #debug print 
     dirn, _ = os.path.split(fname2) 
     if not os.path.exists(dirn): 
      os.makedirs(dirn) 
     shutil.copy(fname, fname2) 

for root, dirs, files in os.walk(tfolder): 
    for name in files: 
     fn = os.path.join(root, name) 
     analyse_file_name(fn) 

回答

0

首先,創建一個字典(一defaultdict更是方便在這裏),將收集這些文件的日期(這是很好的使用re,但由於使用split文件的名稱更容易):

>>> import os 
>>> import re 
>>> pat = r'(\d+)(?:_\d+)?_(\w+?)[\._].*' 
>>> from collections import defaultdict 
>>> dict_date = defaultdict(lambda : defaultdict(list)) 
>>> for fil in os.listdir(path): 
    if os.path.isfile(os.path.join(path, fil)): 
     date, animal = re.match(pat, fil).groups() 
     dict_date[date][animal].append(fil) 


>>> dict_date['20120807'] 
defaultdict(<type 'list'>, {'first': ['20120807_first_day_pic.jpg', '20120807_first_day_sheet.jpg', '20120807_first_day_sheet2.jpg']}) 

然後每個日期,創建一個子文件夾,那裏複製相應的文件:

>>> from shutil import copyfile 
>>> for date in dict_date: 
     for animal in dict_date[date]: 
     try: 
      os.makedirs(os.path.join(path, date, animal)) 
     except os.error: 
      pass 
     for fil in dict_date[date][animal]: 
      copyfile(os.path.join(path, fil), os.path.join(path, date, animal, fil)) 

編輯:考慮到OP的新要求和Khalid的評論。

+1

你應該將'os.mkdirs'調用包裝在try /中,因爲如果該目錄已經存在,它會引發錯誤。 – 2012-07-09 07:48:35

+0

感謝您的幫助,但如果該文件20120809_cat_pic1.jpg 20120809_cat_pic2.jpg 20120809_dog_pic1.jpg 20120809_dog_pic2.jpg我想按日期排序並將狗和貓放入子文件夾 ? – zeromancer 2012-07-09 09:58:06

+0

答案更新:您需要更多級別的字典。請看我的新答案。 – Emmanuel 2012-07-09 10:34:18

2

如果您只是想複製以已知日期字符串格式開頭的文件,那麼類似這樣的事情呢?

def copyfile(filepath, target_dir): 
    p, filename = os.path.split(filepath) 

    # get date component of name 
    date_component = filename.split("_", 1)[0] 

    # try to parse out the date 
    try: 
     d = datetime.datetime.strptime(date_component, "%Y%m%d") 
    except ValueError: 
     print "Could not place: ", filename 
     return 
    target_date_dir = os.path.join(target_dir, str(d.year), str(d.month), str(d.day)) 
    os.makedirs(target_date_dir) 
    shutil.copy(filepath, target_date_dir) 
0
import os, shutil 

src_path = "D:\\Testing\\Src\\" 
dest_path = "D:\\Testing\\Dest\\" 

for file in os.listdir(src_path): 
    if not os.path.isdir(dest_path + file.split("-")[0]): 
     os.mkdir(dest_path + file.split("-")[0]) 
shutil.copy(src_path + file, dest_path + file.split("-")[0]) 
+0

不幫助,因爲它不是從現在開始的時間 – zeromancer 2012-07-09 09:56:32

+0

對不起,沒有正確地讀取問題 – Rakesh 2012-07-10 08:30:39

0

正則表達式一天:) 怎麼樣努力的文件名與

pattern=r'(?P<filedate>(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2}))\_(?P<bloodyrestofname>.*)' 

完成日期,年份等相匹配可以從各自的命名組在比賽中進行檢索。

相關問題