私のファイルシステムには、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」の初期値でない場合、サブフォルダーを作成するためのコードをどこに配置しますか?