雲のメモ帳

猫とクラウドと旅行が好きなインフラエンジニアです。 日々の調べたことや興味が持ったことをこのブログにアウトプットします。

ディレクトリを含まずにファイル圧縮する(zip -j)をPythonで実装する

これはなに?

フォルダをzip化するときにディレクトリ情報を含みたくない時が時々あり、いつもはzip -jで対応していたのですが、zipコマンドが使えない環境だったのでPythonで実装しました。

やること

通常普通にzipコマンド等でzipファイルを作成するとディレクトリを保持した状態でzipファイルが作成されます。
ただ、この状態だとAWS LambdaやGoogle Cloud Functionなどで利用するzipファイルでは解凍後のディレクトリ階層が想定より一段深くなりエラーとなります。そのため、図の下にあるようなディレクトリを保持しないようにzipを作成する必要があります。

zipコマンドが利用できる環境であれば、 zip -j で階層を保持しないzipファイルが作成できるのですが、それをPythonを利用して実施してみました。

f:id:ykoomaru:20220113173219p:plain

ソースコード

処理

  1. 指定したパス直下のフォルダ、ファイル一覧取得
  2. フォルダの場合は、フォルダ内のファイルをZIP化

※ 指定したパス直下にファイルがある場合、ファイルはスキップ

import os
import shutil
import zipfile
path = "./sample/" # ZIP化したいフォルダの親パス
folders = os.listdir(path)
folders

for foldername in folders:
    # フォルダの場合のみZIP化
    if os.path.isdir(path + foldername):
        for dirname, subdirs, filenames in os.walk(path+'/'+foldername):
            zp = zipfile.ZipFile(foldername+'.zip', 'w')
            for fname in filenames:
                zp.write(os.path.join(dirname, fname),arcname=fname)
            zp.close()
        print(foldername+'.zip')

動作確認

以下のような階層で、sampleフォルダを指定した場合

└─sample
    │  test4.txt
    │
    ├─dir1
    │      test1.txt
    │      test2.txt
    │
    └─dir2
            test3.txt

下記画像のようにzipファイルが作成されます。

f:id:ykoomaru:20220113174525p:plain

解凍するとフォルダ直下にファイルが作成されていることが確認できます。 f:id:ykoomaru:20220113174615p:plain