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

スクリプトを実行した後、フォルダー構造は次のようになります。

  • MAIN \ 2742 \ 2742AB.txt
  • MAIN \ 2742 \ 1999 \ 2742AB.tif
  • MAIN \ 2742 \ 1999 \ ED1 \ 2742BB.txt
  • MAIN \ 2742 \ 1999 \ ED2 \ 2742AC.txt
  • MAIN \ 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フォルダのdebugステートメントの結果は次の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

ファイル名を分析する関数を作成する必要があります-その部分を分割し、必要なものに置き換えます。そのような関数の例:

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 に答える
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 に答える