はじめに
jupyter notebookでデータを作成した後、PCに転送する場合、複数ファイルをzipにして送りたいことがよくあります。
pythonでzipファイルを作成したかったのですが、shutil.make_archiveを使うと.ファイルなどのゴミが入ってしまいます。
なので、必要なファイルのみフィルタできないかなと思い作成しました。
ソース
import fnmatch
import zipfile
import os
def make_filter_func(pattern_list, match):
if type(pattern_list) == str:
pattern_list = [pattern_list]
if type(pattern_list) != list:
return None
def _filter_func(f):
for p in pattern_list:
if fnmatch.fnmatch(f, p):
return match
return not match
return _filter_func
def get_file_tree(path, archive_list, ignore_list):
filter_func = lambda x:True
dfilter_func = filter_func
if archive_list is not None:
filter_func = make_filter_func(archive_list, True)
elif ignore_list is not None:
filter_func = make_filter_func(ignore_list, False)
dfilter_func = filter_func
for root, dirs, files in os.walk(path):
yield from (os.path.join(root, f) for f in files if filter_func(f))
filtered_dirs = [d for d in dirs if dfilter_func(d)]
dirs.clear()
dirs.extend(filtered_dirs)
def make_archive(path, archive_list=None, ignore_list='.*'):
path_len = len(path)
with zipfile.ZipFile(path + '.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zip_f:
for f in get_file_tree(path, archive_list, ignore_list):
zip_f.write(f, arcname=f[path_len + 1:])
使い方
指定したディレクトリをzip化します。
デフォルトで.ファイルは無視します。
make_archive(path, archive_list, ignore_list)
path zip化したいディレクトリ名。同じディレクトリにhoge.zipを作成します。
archive_list 格納したいパターン。複数の場合はリスト指定
ignore_list 格納したくないパターン。複数の場合はリスト指定
archive_listとignore_list同時に指定した場合は、ignore_listは無視します。
ignore_listはディレクトリ名もマッチします。
よかったら使ってくださいね。