2012-07-09 129 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>.*)' 

完成日期,年份等相匹配可以从各自的命名组在比赛中进行检索。

相关问题