【Python】7zipでフォルダごとに圧縮する

ファイルサーバの容量ってすぐ無くなりますよね。
いくらでもお金を掛けられれば良いのですが、現実はそうでない。
容量確保のためにフォルダごとに圧縮したくなり作成しました。

やること
・指定ディレクトリ下のフォルダを列挙する
・7zipに圧縮する
・フォルダごとに実行する

これを2つの方法でやってみたいと思います。
・その1_Windows環境でコマンドラインオプションで。
・その2_Py7zrで。

どちらも前提として「7zip」が必要があります。
公式ウェブサイトからインストールしておきましょう!
その1はWindows環境のみですが、別のモジュールをインストール不要です。
その2はPythonがインストールされていれば、WindowsやLinux、Macなど、Pythonがサポートする多くのオペレーティングシステムで使える方法です。

どちらのやり方でも、複数ファイル、複数フォルダをまとめて圧縮できるので、手間が掛かりません。

それでは順番に見ていきましょう!

目次

その1_Windows環境でコマンドラインオプションで

指定ディレクトリ下のフォルダを列挙する

指定ディレクトリ下のフォルダを列挙します。
今回は、実行ファイルと同じ階層の「target」以下のフォルダを対象にします。

「folder1」と「folder2」ですね。最終的にこれらがそれぞれ.7z形式の圧縮ファイルになればOKです。

まずはフォルダを列挙します。

import os

path_dir = "./target"# 圧縮するディレクトリのパス 

folder_list = []

file_list = os.listdir(path_dir)

for file_name in file_list:
    if os.path.isdir(os.path.join(path_dir, file_name)):
        folder_list.append(file_name)

上記では、いったんディレクトリ下にあるものすべてでリストを作成します。
その中からフォルダのみを選んでフォルダリストにしています。

7zipに圧縮する

話は変わって、圧縮についてです。
7-zipはコマンドラインで圧縮ができます。(なので今回はPythonですが、バッチファイルだけでも記述できるそうです。)

import subprocess
path_exe = r'C:\Program Files\7-Zip\7z.exe'# 7zip実行ファイルのパス
result = subprocess.run(args)

Pythonから実行ファイルを呼び出すにはsubprocessを使います。
引数で圧縮対象などを指定します。上記は引数部分(args)を指定していないので動きませんが、骨子だけ抜き出すとこういう感じです。

引数部分も指定すると次です。

import subprocess

path_exe = r'C:\Program Files\7-Zip\7z.exe'# 7zip実行ファイルのパス
path_dir = "./target"# 圧縮するディレクトリのパス  

item_path = os.path.join(path_dir, item)
comp_name = f"{item}.7z"
#絶対パスで出力先込みで指定
comp_name = os.path.abspath(os.path.join(path_dir, comp_name))
args = (
       path_exe, 
       'a', 
       comp_name, # 圧縮後のファイル
       item_path, # 圧縮対象フォルダ
)

result = subprocess.run(args)

圧縮後のファイルを、指定ディレクトリ下に置きたかったので、絶対パス指定で圧縮後のファイル名を設定しました。

フォルダごとに実行する

フォルダごとに実行するのはよくある処理ですね。
先ほど作ったフォルダリストを利用します。

for item in folder_list:
     result = subprocess.run(args)

例によって、引数が入っていないですが、イメージは上記のとおりです。

サンプルコードその1

これらを合体したものがこちらです。

import os
import subprocess

path_exe = r'C:\Program Files\7-Zip\7z.exe'# 7zip実行ファイルのパス
path_dir = "./target"# 圧縮するディレクトリのパス  

# ディレクトリ内のフォルダを格納するリストを初期化
folder_list = []

# ディレクトリ内のファイルとフォルダをリストアップ
file_list = os.listdir(path_dir)

# フォルダのみを抽出してリストに格納
for file_name in file_list:
    if os.path.isdir(os.path.join(path_dir, file_name)):
        folder_list.append(file_name)

# リストごとに実行
for item in folder_list:
    item_path = os.path.join(path_dir, item)
    comp_name = f"{item}.7z"
    #絶対パスで出力先込みで指定
    comp_name = os.path.abspath(os.path.join(path_dir, comp_name))
    args = (
        path_exe, 
        'a', 
        comp_name, # 圧縮後のファイル
        item_path, # 圧縮対象フォルダ
    )
    print(f"圧縮対象:{path_dir}/{item}")
    result = subprocess.run(args)
    print(result)

実行結果がこちらです。

無事「folder1.7z」、「folder2.7z」に圧縮することができました。

おまけ_7zipコマンドラインオプション引数のご参考

どんな引数を設定すればよいかは、実行ファイルだけで実行するとヘルプを見ることができます。
例えば次を実行します。

import subprocess
result = subprocess.run(path_exe)

いくつかピックアップしたものが次です。
応用すれば、圧縮率の変更や、パスワード設定もできます。

Usage: 7z […] […] [@listfile]
a : Add files to archive

— : Stop switches and @listfile parsing
-m{Parameters} : set compression Method
-mmt[N] : set number of CPU threads
-mx[N] : set compression level: -mx1 (fastest) … -mx9 (ultra)
-o{Directory} : set Output directory
-p{Password} : set Password

その2_Py7zrで

subprocessを使う方法も便利ですが、環境に依存します。
例えば、WindowsでもLinuxでも使いたい場合に共通して動作しないことがあります。
そこで、別の方法として、「Py7zr」を使う方法をご紹介します。

Py7zrをインストールする

まずは何はともあれモジュールのインストールからです。

pip install py7zr

7zipに圧縮する

基本的な使用例です。
対象ファイル(フォルダ)を開き、圧縮後のファイル名を指定してアーカイブとして書き込みます。

import py7zr

# 使用例
def compress_to_7zip(source_file, destination_file):
    with py7zr.SevenZipFile(destination_file, 'w') as archive:
        archive.writeall(source_file)item_path = 'example.txt'  # 圧縮する元のファイル

item_path = 'example.txt'  # 圧縮する元のファイル
comp_name = 'compressed.7z'  # 圧縮後のファイル名
compress_to_7zip(item_path, comp_name)

基本的な使い方はその1と大きく変わりません。
また、その他の要素(フォルダの列挙など)はその1と同じです。
ということでサンプルコードを見てみましょう。

その2_サンプルコード

その1のサンプルコードとほぼ同様です。
最後の「compress_to_7zip(item_path, comp_name)」だけ置き換えた格好です。
関数にしているので、こちらの方がスッキリしました。

import py7zr
import os

def compress_to_7zip(source_file, destination_file):
    with py7zr.SevenZipFile(destination_file, 'w') as archive:
        archive.writeall(source_file)


path_dir = "./target"# 圧縮するディレクトリのパス  

# ディレクトリ内のフォルダを格納するリストを初期化
folder_list = []

# ディレクトリ内のファイルとフォルダをリストアップ
file_list = os.listdir(path_dir)
print(file_list)

# フォルダのみを抽出してリストに格納
for file_name in file_list:
    if os.path.isdir(os.path.join(path_dir, file_name)):
        folder_list.append(file_name)

# リストごとに実行
for item in folder_list:
    item_path = os.path.join(path_dir, item)
    comp_name = f"{item}.7z"
    comp_name = os.path.abspath(os.path.join(path_dir, comp_name))
    compress_to_7zip(item_path, comp_name)   

実行結果は同様ですので割愛します。

おまけ_py7zrでパスワード設定する方法

最後にpy7zrでパスワード設定する方法をご紹介します。
引数を追加するだけです。

import py7zr

def compress_to_7zip_with_password(source_file, destination_file, encryption):
    with py7zr.SevenZipFile(destination_file, 'w', password=encryption) as archive:
        archive.writeall(source_file)

今回は7zipでフォルダごとに圧縮する方法を2通りご紹介しました。
いかがでしたでしょうか。
大量に圧縮対象がある場合でも、この方法なら手間が掛かりません。

今回は以上になります。
少しでもお役に立てれば幸いです。
それでは、読んで頂きありがとうございました!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次