1

我的文件系统包含大量文件夹,文件夹名称的格式为 4 位。每个文件夹中都有不同数量的不同格式的文件,其名称与文件夹名称相对应,有些还带有字母和/或日期。我想做的是搜索每个文件夹,如果一年的格式为“19??” 或“20??” 找到后,创建一个标有该年份的文件夹。如果文件名还包含表达式“ED*”,请创建一个带有该标签的子文件夹。创建所有文件夹后,将所有文件复制到其相应的文件夹中,并将名称删除到前 6 个字符。此文件结构将在单独的驱动器上创建。

示例:文件夹 MAIN 包含许多子文件夹,例如 2742、2830、3417 等。文件夹 2742 包含文件

  • 2742AB.txt
  • 2742AB_1999.tif
  • 2742BB_1999_ED1.txt
  • 2742AC_1999_ED2_FINAL.txt
  • 2742CC_2001_ED4.tif

运行脚本后,文件夹结构应如下所示:

  • 主\2742\2742AB.txt
  • 主\2742\1999\2742AB.tif
  • 主\2742\1999\ED1\2742BB.txt
  • 主\2742\1999\ED2\2742AC.txt
  • 主\2742\2001\ED4\2742CC.tif

在这里搜索类似示例后使用各种代码片段,我想出了以下内容: import os folder = 'C:\MAIN' os.chdir(folder)

dirlist = []
for dirname, dirnames, filenames in os.walk(folder):
    for subdirname in dirnames:
        dirlist.append(subdirname)
    for filename in filenames:
        dirlist.append(filename)

我的问题是下一部分,即修改上面的搜索以首先检查该值是否已经在列表中。如果它在列表中,则继续搜索,否则检查文件名是否包含正则表达式,如果包含,则将其添加到数组中。在(某种)伪代码中:

initialise list years
#search through folders etc
for filenames in folders
    if filename contains either regex
        for values in years
            if filename exists
                skip it and continue searching
            else
                append filename to years

我在这里查看了有关使用正则表达式等搜索文件夹的各种答案,但我不完全确定我使用的方法是否正确。对我使用的方法的任何建议和/或评论将不胜感激。

编辑我编辑的代码,使用下面 Michal 的建议并自己修改一下:

import os, re, shutil
tfolder = 'C:\\MAIN'
os.chdir(tfolder)

re_year19xx = re.compile('(19[0-9][0-9])')
re_year20xx = re.compile('(20[0-9][0-9])')
re_ed = re.compile('(ed[0-9]\d+)', re.IGNORECASE)
destPath = 'C:\\DEST'

filePath, coords = os.path.split(fname)
coordsFolder = coords[:4]
coordsFname = coords[:6]
coordsExt = os.path.splitext(fname)
year = ' ' #create variable year
ed = ' ' #create variable ed to store the edition number if necessary
bname = fname #the original file name
for re_year in (re_year19xx, re_year20xx):
    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
        print(year)
        bname.replace(year, ' ')
        re_searchEd = re_ed.search(fname)
        if re_searchEd:
            ed = re_searchEd.group(1)
            bname.replace(ed, ' ')
    os.chdir(destPath)  
    fname2 = os.path.join(destPath, coordsFolder,year, ed) + coordsFname + coordsExt[1]
    print('%s -> %s' % (fname, fname2))
    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)

再次查看我的代码,一切似乎都正常工作,直到它必须创建子文件夹,即一旦coordsFolder创建,如果year不是空白,创建子文件夹,如果ed不是空白,创建子文件夹,然后将原始文件复制到相应的子文件夹并重命名。文件夹的调试print语句结果2742如下:

C:\MAIN\2742\2742AB.txt -> C:\DEST\2742\year\ed2742AB.txt
C:\MAIN\2742\2742AB.txt -> C:\DEST\2742\year\ed2742AB.txt
1999
C:\MAIN\2742\2742AB_1999.tif -> C:\DEST\2742\1999\ed2742AB.tif
C:\MAIN\2742\2742AB_1999.tif -> C:\DEST\2742\1999\ed2742AB.tif
1999
C:\MAIN\2742\2742AC_1999_ED2_final.tif -> C:\DEST\2742\1999\ed2742AC.tif
C:\MAIN\2742\2742AC_1999_ED2_final.tif -> C:\DEST\2742\1999\ed2742AC.tif
1999
C:\MAIN\2742\2742BB_1999_ED1.txt -> C:\DEST\2742\1999\ed2742BB.txt
C:\MAIN\2742\2742BB_1999_ED1.txt -> C:\DEST\2742\1999\ed2742BB.txt
C:\MAIN\2742\2742CC_2001_ED4.tif -> C:\DEST\2742\year\ed2742CC.tif
2001
C:\MAIN\2742\2742CC_2001_ED4.tif -> C:\DEST\2742\2001\ed2742CC.tif
1999

编辑添加检查值后year

if year is 'year':
    fname2 = os.path.join(destPath, coordsFolder) + '\\' + coordsFname + coordsExt[1]
else:
    fname2 = os.path.join(destPath, coordsFolder,year) + '\\' + coordsFname + coordsExt[1]

路径是正确创建的 npw 并且文件被复制到正确的位置并正确重命名!所以问题的最后一部分现在适用于ed子文件夹。目前,代码只是忽略了文件名中包含“ED1”、“ED2”等的部分。如果 的值ed不是“ed”> 的初始值,我在哪里放置创建子文件夹的代码

4

2 回答 2

0

我的问题的最终答案(经过大量编辑和@Michal Niklas 的大量帮助:

import os, re, shutil

tfolder = 'C:\\MAIN'

os.chdir(tfolder)

re_year19xx = re.compile('(19[0-9][0-9])')
re_year20xx = re.compile('(20[0-9][0-9])')

re_ed = re.compile('(ED[0-9])')
destPath = 'C:\\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[:4]
    coordsFname = coords[:6]
    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_year19xx, re_year20xx):
        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)
于 2012-04-23T13:37:24.953 回答
0

您应该创建分析文件名的函数 - 拆分其部分,用您想要的内容替换它们等。此类函数的示例:

re_year19xx = re.compile('(19\d\d)')
re_year20xx = re.compile('(20\d\d)')

re_ed = re.compile('(ed\d+)', re.IGNORECASE)


def analyze_file_name(fname):
    digits = fname[:4]
    year = ''
    ed = ''
    bname = fname
    for re_year in (re_year19xx, re_year20xx):
        rx = re_year.search(fname)
        if rx:
            year = rx.group(1)
            bname = bname.replace(year, '')
    rx = re_ed.search(fname)
    if rx:
        ed = rx.group(1)
        bname = bname.replace(ed, '')
    fname2 = os.path.join('MAIN', digits, year, ed, bname)
    fname2 = fname2.replace('_', '')
    print('%s -> %s' % (fname, fname2))

如果要将文件移动(重命名)到新目标,则可以检查并创建目标目录,然后将文件移动到那里。代码可能如下所示:

    ...
    fname2 = fname2.replace('_', '')
    dirn, _ = os.path.split(fname2)
    if not os.path.exists(dirn):
        os.makedirs(dirn)
    os.rename(fname, fname2)
    print('%s -> %s' % (fname, fname2))

如果您想同时拥有源文件和目标文件,则os.rename()可以使用。shutil.copy()

你也有问题os.walk()。在当前形式中,您将多次获得相同的文件名,并且analyze_file_name()只会获得文件名的最后一部分(即没有目录)。我将向您展示如何获得完整的文件名:

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

您还可以将带有目录名称的额外参数添加到analyse_file_name().

完整版本基于您创建 dest 目录的最后一个来源:

def analyse_file_name(fname):
    filePath, coords = os.path.split(fname)
    coordsFolder = coords[:4]
    coordsFname = coords[:6]
    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_year19xx, re_year20xx):
        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
            print(year)
            bname.replace(year, ' ')
            re_searchEd = re_ed.search(fname)
            if re_searchEd:
                ed = re_searchEd.group(1)
                bname.replace(ed, ' ')
        fname2 = os.path.join(destPath, coordsFolder,year, ed)
        fname2 = fname2 + coordsFname + coordsExt[1]
        print('%s -> %s' % (fname, fname2))
        dirn, _ = os.path.split(fname2)
        if not os.path.exists(dirn):
            os.makedirs(dirn)
        shutil.copy(fname, fname2)
于 2012-04-05T08:19:04.773 回答