파이썬에서 디렉토리의 zip 아카이브를 만드는 방법은 무엇입니까?
-
13-09-2019 - |
문제
파이썬에서 디렉토리 구조의 zip 아카이브를 어떻게 만들 수 있습니까?
해결책
다른 사람들이 지적했듯이, 당신은 사용해야합니다 압축 파일. 이 문서는 어떤 기능을 사용할 수 있는지 알려주지 만 실제로 전체 디렉토리를 지퍼하는 방법을 설명하지는 않습니다. 일부 예제 코드로 설명하는 것이 가장 쉽다고 생각합니다.
#!/usr/bin/env python
import os
import zipfile
def zipdir(path, ziph):
# ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
ziph.write(os.path.join(root, file))
if __name__ == '__main__':
zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
zipdir('tmp/', zipf)
zipf.close()
다음에서 조정 : http://www.devshed.com/c/a/python/python-unzipped/
다른 팁
가장 쉬운 방법은 사용하는 것입니다 shutil.make_archive
. 지퍼 형식과 타르 형식을 모두 지원합니다.
import shutil
shutil.make_archive(output_filename, 'zip', dir_name)
전체 디렉토리 (예 : 특정 파일 건너 뛰기)를 줄이는 것보다 더 복잡한 일을 해야하는 경우 zipfile
다른 사람들이 제안한 모듈.
내용을 추가합니다 mydirectory
모든 파일 및 하위 디렉토리를 포함한 새 ZIP 파일에 :
import os
import zipfile
zf = zipfile.ZipFile("myzipfile.zip", "w")
for dirname, subdirs, files in os.walk("mydirectory"):
zf.write(dirname)
for filename in files:
zf.write(os.path.join(dirname, filename))
zf.close()
파이썬에서 디렉토리 구조의 zip 아카이브를 어떻게 만들 수 있습니까?
파이썬 스크립트에서
Python 2.7+에서 shutil
a make_archive
기능.
from shutil import make_archive
make_archive(
'zipfile_name',
'zip', # the archive format - or tar, bztar, gztar
root_dir=None, # root for archive - current working dir if None
base_dir=None) # start archiving from here - cwd if None too
여기에서 지퍼 아카이브의 이름이 지정됩니다 zipfile_name.zip
. 만약에 base_dir
더 멀리 떨어져 있습니다 root_dir
파일이 아닌 파일을 제외합니다 base_dir
, 그러나 여전히 부모의 파일을 root_dir
.
Cygwin에서 2.7로 이것을 테스트하는 문제가있었습니다. CWD에 대한 root_dir 인수를 원합니다.
make_archive('zipfile_name', 'zip', root_dir='.')
쉘에서 파이썬을 사용합니다
당신은 또한 쉘에서 파이썬으로 이것을 사용할 수 있습니다. zipfile
기준 치수:
$ python -m zipfile -c zipname sourcedir
어디에 zipname
원하는 대상 파일의 이름입니다 (추가 .zip
원한다면 자동으로 수행하지 않습니다) 및 Sourcedir는 디렉토리의 경로입니다.
Python을 Zipping (또는 부모를 원하지 않음) :
Python 패키지를 __init__.py
그리고 __main__.py
, 그리고 당신은 부모 dir를 원하지 않습니다.
$ python -m zipfile -c zipname sourcedir/*
그리고
$ python zipname
패키지를 실행합니다. (지핑 아카이브에서 입구 지점으로 하위 포장지를 실행할 수 없습니다.)
파이썬 앱을지는 것 :
Python3.5+가 있고 특히 Python 패키지를 지그팅하려면 사용하십시오. zipapp:
$ python -m zipapp myapp
$ python myapp.pyz
이 함수는 디렉토리 트리를 재귀 적으로 압축하고 압축 파일 및 아카이브에서 올바른 상대 파일 이름을 녹음합니다. 아카이브 항목은 zip -r output.zip source_dir
.
import os
import zipfile
def make_zipfile(output_filename, source_dir):
relroot = os.path.abspath(os.path.join(source_dir, os.pardir))
with zipfile.ZipFile(output_filename, "w", zipfile.ZIP_DEFLATED) as zip:
for root, dirs, files in os.walk(source_dir):
# add directory (needed for empty dirs)
zip.write(root, os.path.relpath(root, relroot))
for file in files:
filename = os.path.join(root, file)
if os.path.isfile(filename): # regular files only
arcname = os.path.join(os.path.relpath(root, relroot), file)
zip.write(filename, arcname)
Python Standard Library 세트의 일부인 Shutil을 사용하십시오. Shutil 사용은 매우 간단합니다 (아래 코드 참조).
- 1st Arg : 결과 Zip/Tar 파일의 파일 이름,
- 두 번째 arg : zip/tar,
- 3 번째 arg : dir_name
암호:
import shutil
shutil.make_archive('/home/user/Desktop/Filename','zip','/home/username/Desktop/Directory')
결과 ZIP 파일에 압축을 추가하려면 확인하십시오. 이 링크.
변경해야합니다.
zip = zipfile.ZipFile('Python.zip', 'w')
에게
zip = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
나는 몇 가지 변경을했다 Mark Byers가 제공 한 코드. 아래 함수는 빈 디렉토리가있는 경우 빈 디렉토리를 추가합니다. 예제는 지퍼에 추가 된 경로가 무엇인지 더 명확하게 만들어야합니다.
#!/usr/bin/env python
import os
import zipfile
def addDirToZip(zipHandle, path, basePath=""):
"""
Adding directory given by \a path to opened zip file \a zipHandle
@param basePath path that will be removed from \a path when adding to archive
Examples:
# add whole "dir" to "test.zip" (when you open "test.zip" you will see only "dir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir')
zipHandle.close()
# add contents of "dir" to "test.zip" (when you open "test.zip" you will see only it's contents)
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir', 'dir')
zipHandle.close()
# add contents of "dir/subdir" to "test.zip" (when you open "test.zip" you will see only contents of "subdir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir/subdir', 'dir/subdir')
zipHandle.close()
# add whole "dir/subdir" to "test.zip" (when you open "test.zip" you will see only "subdir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir/subdir', 'dir')
zipHandle.close()
# add whole "dir/subdir" with full path to "test.zip" (when you open "test.zip" you will see only "dir" and inside it only "subdir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir/subdir')
zipHandle.close()
# add whole "dir" and "otherDir" (with full path) to "test.zip" (when you open "test.zip" you will see only "dir" and "otherDir")
zipHandle = zipfile.ZipFile('test.zip', 'w')
addDirToZip(zipHandle, 'dir')
addDirToZip(zipHandle, 'otherDir')
zipHandle.close()
"""
basePath = basePath.rstrip("\\/") + ""
basePath = basePath.rstrip("\\/")
for root, dirs, files in os.walk(path):
# add dir itself (needed for empty dirs
zipHandle.write(os.path.join(root, "."))
# add files
for file in files:
filePath = os.path.join(root, file)
inZipPath = filePath.replace(basePath, "", 1).lstrip("\\/")
#print filePath + " , " + inZipPath
zipHandle.write(filePath, inZipPath)
위는 간단한 경우에 작동 해야하는 간단한 기능입니다. 내 요점에서 더 우아한 수업을 찾을 수 있습니다.https://gist.github.com/eccenux/17526123107ca0ac28e6
당신은 아마도보고 싶을 것입니다 zipfile
기준 치수; 문서가 있습니다 http://docs.python.org/library/zipfile.html.
당신은 또한 원할 수도 있습니다 os.walk()
디렉토리 구조를 색인합니다.
Python3, Pathlib 및 Zipfile을 사용하여 도움이 될 수있는 다른 코드 예제가 있습니다. 모든 OS에서 작동해야합니다.
from pathlib import Path
import zipfile
from datetime import datetime
DATE_FORMAT = '%y%m%d'
def date_str():
"""returns the today string year, month, day"""
return '{}'.format(datetime.now().strftime(DATE_FORMAT))
def zip_name(path):
"""returns the zip filename as string"""
cur_dir = Path(path).resolve()
parent_dir = cur_dir.parents[0]
zip_filename = '{}/{}_{}.zip'.format(parent_dir, cur_dir.name, date_str())
p_zip = Path(zip_filename)
n = 1
while p_zip.exists():
zip_filename = ('{}/{}_{}_{}.zip'.format(parent_dir, cur_dir.name,
date_str(), n))
p_zip = Path(zip_filename)
n += 1
return zip_filename
def all_files(path):
"""iterator returns all files and folders from path as absolute path string
"""
for child in Path(path).iterdir():
yield str(child)
if child.is_dir():
for grand_child in all_files(str(child)):
yield str(Path(grand_child))
def zip_dir(path):
"""generate a zip"""
zip_filename = zip_name(path)
zip_file = zipfile.ZipFile(zip_filename, 'w')
print('create:', zip_filename)
for file in all_files(path):
print('adding... ', file)
zip_file.write(file)
zip_file.close()
if __name__ == '__main__':
zip_dir('.')
print('end!')
다음은 NUX가 제공 한 답변에 대한 변형입니다.
def WriteDirectoryToZipFile( zipHandle, srcPath, zipLocalPath = "", zipOperation = zipfile.ZIP_DEFLATED ):
basePath = os.path.split( srcPath )[ 0 ]
for root, dirs, files in os.walk( srcPath ):
p = os.path.join( zipLocalPath, root [ ( len( basePath ) + 1 ) : ] )
# add dir
zipHandle.write( root, p, zipOperation )
# add files
for f in files:
filePath = os.path.join( root, f )
fileInZipPath = os.path.join( p, f )
zipHandle.write( filePath, fileInZipPath, zipOperation )
아래를 시도해보십시오. 그것은 나를 위해 일했습니다.
import zipfile, os
zipf = "compress.zip"
def main():
directory = r"Filepath"
toZip(directory)
def toZip(directory):
zippedHelp = zipfile.ZipFile(zipf, "w", compression=zipfile.ZIP_DEFLATED )
list = os.listdir(directory)
for file_list in list:
file_name = os.path.join(directory,file_list)
if os.path.isfile(file_name):
print file_name
zippedHelp.write(file_name)
else:
addFolderToZip(zippedHelp,file_list,directory)
print "---------------Directory Found-----------------------"
zippedHelp.close()
def addFolderToZip(zippedHelp,folder,directory):
path=os.path.join(directory,folder)
print path
file_list=os.listdir(path)
for file_name in file_list:
file_path=os.path.join(path,file_name)
if os.path.isfile(file_path):
zippedHelp.write(file_path)
elif os.path.isdir(file_name):
print "------------------sub directory found--------------------"
addFolderToZip(zippedHelp,file_name,path)
if __name__=="__main__":
main()
공통 그래픽 파일 관리자의 압축 폴더와 같은 기능을 원한다면 다음 코드를 사용할 수 있습니다. 압축 파일 기준 치수. 이 코드를 사용하면 경로가있는 zip 파일이 루트 폴더로 표시됩니다.
import os
import zipfile
def zipdir(path, ziph):
# Iterate all the directories and files
for root, dirs, files in os.walk(path):
# Create a prefix variable with the folder structure inside the path folder.
# So if a file is at the path directory will be at the root directory of the zip file
# so the prefix will be empty. If the file belongs to a containing folder of path folder
# then the prefix will be that folder.
if root.replace(path,'') == '':
prefix = ''
else:
# Keep the folder structure after the path folder, append a '/' at the end
# and remome the first character, if it is a '/' in order to have a path like
# folder1/folder2/file.txt
prefix = root.replace(path, '') + '/'
if (prefix[0] == '/'):
prefix = prefix[1:]
for filename in files:
actual_file_path = root + '/' + filename
zipped_file_path = prefix + filename
zipf.write( actual_file_path, zipped_file_path)
zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
zipdir('/tmp/justtest/', zipf)
zipf.close()
현대 파이썬 (3.6+)을 사용합니다 pathlib
간결한 OOP와 같은 경로 처리를위한 모듈 및 pathlib.Path.rglob()
재귀 적 글로브를 위해. 내가 알 수있는 한, 이것은 George V. Reilly의 대답과 같습니다. 압축과의 ZIPS, 최상위 요소는 디렉토리이며, 비어있는 DIRS를 유지하고, 상대 경로를 사용합니다.
from pathlib import Path
from zipfile import ZIP_DEFLATED, ZipFile
from os import PathLike
from typing import Union
def zip_dir(zip_name: str, source_dir: Union[str, PathLike]):
src_path = Path(source_dir).expanduser().resolve(strict=True)
with ZipFile(zip_name, 'w', ZIP_DEFLATED) as zf:
for file in src_path.rglob('*'):
zf.write(file, file.relative_to(src_path.parent))
참고 : 선택적 유형 힌트가 지적한대로 zip_name
경로 개체가 될 수 없습니다 (3.6.2+로 고정됩니다).
더 많은 유연성을 제공하려면 예를 들어 이름으로 디렉토리/파일을 선택하십시오.
import os
import zipfile
def zipall(ob, path, rel=""):
basename = os.path.basename(path)
if os.path.isdir(path):
if rel == "":
rel = basename
ob.write(path, os.path.join(rel))
for root, dirs, files in os.walk(path):
for d in dirs:
zipall(ob, os.path.join(root, d), os.path.join(rel, d))
for f in files:
ob.write(os.path.join(root, f), os.path.join(rel, f))
break
elif os.path.isfile(path):
ob.write(path, os.path.join(rel, basename))
else:
pass
파일 트리의 경우 :
.
├── dir
│ ├── dir2
│ │ └── file2.txt
│ ├── dir3
│ │ └── file3.txt
│ └── file.txt
├── dir4
│ ├── dir5
│ └── file4.txt
├── listdir.zip
├── main.py
├── root.txt
└── selective.zip
예를 들어 선택할 수 있습니다 dir4
그리고 root.txt
:
cwd = os.getcwd()
files = [os.path.join(cwd, f) for f in ['dir4', 'root.txt']]
with zipfile.ZipFile("selective.zip", "w" ) as myzip:
for f in files:
zipall(myzip, f)
아니면 그냥 listdir
스크립트 호출 디렉토리에서 모든 것을 추가하십시오.
with zipfile.ZipFile("listdir.zip", "w" ) as myzip:
for f in os.listdir():
if f == "listdir.zip":
# Creating a listdir.zip in the same directory
# will include listdir.zip inside itself, beware of this
continue
zipall(myzip, f)
현재 디렉토리에서 모든 폴더 (서브 디렉토리)를 지퍼로 지정한다고 가정 해 봅시다.
for root, dirs, files in os.walk("."):
for sub_dir in dirs:
zip_you_want = sub_dir+".zip"
zip_process = zipfile.ZipFile(zip_you_want, "w", zipfile.ZIP_DEFLATED)
zip_process.write(file_you_want_to_include)
zip_process.close()
print("Successfully zipped directory: {sub_dir}".format(sub_dir=sub_dir))
다음은 Pathlib 및 컨텍스트 관리자를 사용하는 현대적인 접근 방식입니다. 파일을 하위 폴더가 아닌 지퍼에 직접 넣습니다.
def zip_dir(filename: str, dir_to_zip: pathlib.Path):
with zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
# Use glob instead of iterdir(), to cover all subdirectories.
for directory in dir_to_zip.glob('**'):
for file in directory.iterdir():
if not file.is_file():
continue
# Strip the first component, so we don't create an uneeded subdirectory
# containing everything.
zip_path = pathlib.Path(*file.parts[1:])
# Use a string, since zipfile doesn't support pathlib directly.
zipf.write(str(file), str(zip_path))
Reimund 및 Morten Zilmer의 의견 (상대 경로 포함 및 빈 디렉토리 포함)으로 Mark Byers의 솔루션을 통합하여 기능을 준비했습니다. 모범 사례로 with
ZipFile의 파일 구성에 사용됩니다.
이 함수는 또한 ZIPPER DIRECTORY 이름과 '.zip'확장자가있는 기본 zip 파일 이름을 준비합니다. 따라서 하나의 인수만으로 작동합니다 : 소스 디렉토리는 지퍼를 찍습니다.
import os
import zipfile
def zip_dir(path_dir, path_file_zip=''):
if not path_file_zip:
path_file_zip = os.path.join(
os.path.dirname(path_dir), os.path.basename(path_dir)+'.zip')
with zipfile.ZipFile(path_file_zip, 'wb', zipfile.ZIP_DEFLATED) as zip_file:
for root, dirs, files in os.walk(path_dir):
for file_or_dir in files + dirs:
zip_file.write(
os.path.join(root, file_or_dir),
os.path.relpath(os.path.join(root, file_or_dir),
os.path.join(path_dir, os.path.pardir)))
# import required python modules
# You have to install zipfile package using pip install
import os,zipfile
# Change the directory where you want your new zip file to be
os.chdir('Type your destination')
# Create a new zipfile ( I called it myfile )
zf = zipfile.ZipFile('myfile.zip','w')
# os.walk gives a directory tree. Access the files using a for loop
for dirnames,folders,files in os.walk('Type your directory'):
zf.write('Type your Directory')
for file in files:
zf.write(os.path.join('Type your directory',file))
글쎄, 제안을 읽은 후 나는 "재미있는"디렉토리 이름 (절대 같은 이름)을 만들지 않고 2.7.x와 함께 작동하는 매우 유사한 방식을 생각해 냈으며 Zip 안에 지정된 폴더 만 생성합니다.
또는 선택한 디렉토리의 내용과 함께 내부에 폴더를 포함하기 위해 ZIP가 필요한 경우를 대비하여.
def zipDir( path, ziph ) :
"""
Inserts directory (path) into zipfile instance (ziph)
"""
for root, dirs, files in os.walk( path ) :
for file in files :
ziph.write( os.path.join( root, file ) , os.path.basename( os.path.normpath( path ) ) + "\\" + file )
def makeZip( pathToFolder ) :
"""
Creates a zip file with the specified folder
"""
zipf = zipfile.ZipFile( pathToFolder + 'file.zip', 'w', zipfile.ZIP_DEFLATED )
zipDir( pathToFolder, zipf )
zipf.close()
print( "Zip file saved to: " + pathToFolder)
makeZip( "c:\\path\\to\\folder\\to\\insert\\into\\zipfile" )
zip 파일을 만들기 위해 함수.
def CREATEZIPFILE(zipname, path):
#function to create a zip file
#Parameters: zipname - name of the zip file; path - name of folder/file to be put in zip file
zipf = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)
zipf.setpassword(b"password") #if you want to set password to zipfile
#checks if the path is file or directory
if os.path.isdir(path):
for files in os.listdir(path):
zipf.write(os.path.join(path, files), files)
elif os.path.isfile(path):
zipf.write(os.path.join(path), path)
zipf.close()
보관할 부모 디렉토리의 폴더 계층 구조를 유지하는 간결한 방법 :
import glob
import zipfile
with zipfile.ZipFile(fp_zip, "w", zipfile.ZIP_DEFLATED) as zipf:
for fp in glob(os.path.join(parent, "**/*")):
base = os.path.commonpath([parent, fp])
zipf.write(fp, arcname=fp.replace(base, ""))
원한다면 사용하도록 변경할 수 있습니다. pathlib
파일 글로브.
여기에 많은 답변이 있으며, 원래 답변을 기반으로하는 내 버전에 기여할 수 있기를 바랍니다. zipfile
설정 및 정렬 os.walk()
, 주문 된 출력을 갖기 위해.
이 폴더와 파일 (다른 폴더 중에서)을 사용하여 .zip
각각 cap_
폴더:
$ tree -d
.
├── cap_01
| ├── 0101000001.json
| ├── 0101000002.json
| ├── 0101000003.json
|
├── cap_02
| ├── 0201000001.json
| ├── 0201000002.json
| ├── 0201001003.json
|
├── cap_03
| ├── 0301000001.json
| ├── 0301000002.json
| ├── 0301000003.json
|
├── docs
| ├── map.txt
| ├── main_data.xml
|
├── core_files
├── core_master
├── core_slave
프로세스를 더 잘 이해하기위한 의견과 함께 내가 적용한 내용은 다음과 같습니다.
$ cat zip_cap_dirs.py
""" Zip 'cap_*' directories. """
import os
import zipfile as zf
for root, dirs, files in sorted(os.walk('.')):
if 'cap_' in root:
print(f"Compressing: {root}")
# Defining .zip name, according to Capítulo.
cap_dir_zip = '{}.zip'.format(root)
# Opening zipfile context for current root dir.
with zf.ZipFile(cap_dir_zip, 'w', zf.ZIP_DEFLATED) as new_zip:
# Iterating over os.walk list of files for the current root dir.
for f in files:
# Defining relative path to files from current root dir.
f_path = os.path.join(root, f)
# Writing the file on the .zip file of the context
new_zip.write(f_path)
기본적으로, 각 반복에 대해 os.walk(path)
, 나는 컨텍스트를 열고있다 zipfile
설정 후 반복을 반복합니다 files
,, 그것은 a list
파일의 root
디렉토리, 현재를 기준으로 각 파일의 상대 경로 형성 root
디렉토리, zipfile
실행중인 맥락.
그리고 출력은 다음과 같이 제시됩니다.
$ python3 zip_cap_dirs.py
Compressing: ./cap_01
Compressing: ./cap_02
Compressing: ./cap_03
각각의 내용을 볼 수 있습니다 .zip
디렉토리, 사용할 수 있습니다 less
명령:
$ less cap_01.zip
Archive: cap_01.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
22017 Defl:N 2471 89% 2019-09-05 08:05 7a3b5ec6 cap_01/0101000001.json
21998 Defl:N 2471 89% 2019-09-05 08:05 155bece7 cap_01/0101000002.json
23236 Defl:N 2573 89% 2019-09-05 08:05 55fced20 cap_01/0101000003.json
-------- ------- --- -------
67251 7515 89% 3 files