スクリプトで、指定されたソースディレクトリ ( ) の内容をsrc
zip ファイル ( dst
) に圧縮する関数を作成しようとしています。たとえば、zip('/path/to/dir', '/path/to/file.zip')
は/path/to/dir
ディレクトリであり、/path/to/file.zip
まだ存在していません。しないでくださいディレクトリ自体を圧縮したいのですが、私の場合はこれで全く違います。ディレクトリ内のファイル (およびサブディレクトリ) を圧縮したいのです。私が試しているのは次のことです:
def zip(src, dst):
zf = zipfile.ZipFile("%s.zip" % (dst), "w")
for dirname, subdirs, files in os.walk(src):
zf.write(dirname)
for filename in files:
zf.write(os.path.join(dirname, filename))
zf.close()
これにより、本質的には の zip が作成されます/
。たとえば、 を zip 形式で圧縮した場合/path/to/dir
、その zip を解凍すると、その中に「path」が含まれるディレクトリが作成され、そのディレクトリ内に「to」が含まれるようになります。
この問題が発生しない機能を持っている人はいますか?
これを強調してもしすぎることはないが、ニーズディレクトリ自体ではなく、ディレクトリ内のファイルを zip 圧縮します。
ベストアンサー1
のzipfile.write()
arcname
メソッドは、zip ファイル内のファイル名を指定するオプションの引数を取ります。
src
これを使って、先頭のパスを削除できます。ここではos.path.abspath()
src
とによって返されるファイル名の両方にos.walk()
共通のプレフィックスがあることを確認します。
#!/usr/bin/env python2.7
import os
import zipfile
def zip(src, dst):
zf = zipfile.ZipFile("%s.zip" % (dst), "w", zipfile.ZIP_DEFLATED)
abs_src = os.path.abspath(src)
for dirname, subdirs, files in os.walk(src):
for filename in files:
absname = os.path.abspath(os.path.join(dirname, filename))
arcname = absname[len(abs_src) + 1:]
print 'zipping %s as %s' % (os.path.join(dirname, filename),
arcname)
zf.write(absname, arcname)
zf.close()
zip("src", "dst")
ディレクトリ構造は次のようになります。
src
└── a
├── b
│ └── bar
└── foo
スクリプトは次のように出力します:
zipping src/a/foo as a/foo
zipping src/a/b/bar as a/b/bar
結果として得られる zip ファイルの内容は次のとおりです。
Archive: dst.zip
Length Date Time Name
-------- ---- ---- ----
0 01-28-13 11:36 a/foo
0 01-28-13 11:36 a/b/bar
-------- -------
0 2 files