2017/04/02

Python Tips:特定のサイズ以上のファイルを検索したい

バタバタしており久しぶりの投稿になってしまいました。

今回は Python で指定されたサイズ以上のファイルを検索する方法をご紹介します。

これを実現するアプローチとしてはいくつかの方法が考えられるかと思いますが、今回は標準ライブラリの pathlib を使った方法をご紹介してみたいと思います。

from pathlib import Path

pathlib の Path クラスを使えば OOP スタイルで OS のファイルシステムを操作することができます。

Path クラスの数あるメソッドのうち次の 4 つほどをおさえておけば、ファイルを探す処理の実装には十分でしょう。

- iterdir() ディレクトリの中にあるファイル / ディレクトリを全件返す
- is_dir() ディレクトリかどうかをチェックする
- is_file() ファイルかどうかをチェックする
- stat() ファイルサイズを含むファイルのメタ情報を返す

サンプルコードを書いてみます。

# coding: utf-8
from pathlib import Path

def search_files(path, size_min_in_byte):
    """指定されたパスの下にある指定されたサイズ以上のファイル名を一覧表示する
    """
    size_min_in_mb = size_min_in_byte << 20

    p = Path(path)

    # 指定されたパス以下のファイルを再帰的にチェックする
    # 指定されたサイズ以上のファイルは「 10MB  ファイル名」といった感じに表示する
    for file in p.iterdir():
        if file.is_dir():
            search_files(file, size_min_in_byte)
        elif file.is_file():
            size = file.stat().st_size
            if size >= size_min_in_mb:
                # resolve() を使って絶対パスを表示する
                print('{:.1f}MB\t{}'.format(size >> 20, file.resolve()))


if __name__ == '__main__':
    # hayato のデスクトップ以下にあるサイズが 1MB 以上のファイルを表示する
    path = '/Users/hayato/Desktop'
    size_in_mb = 2
    search_files(path, size_in_mb)


ファイル名を script_name.py として保存しターミナルで実行してみましょう。私の環境では例えば次のような出力が出ます。

$ python script_name.py
3.5MB /Users/hayato/Desktop/山月記.md
2.2MB /Users/hayato/Desktop/弟子.md
2.7MB /Users/hayato/Desktop/李陵.md

これはちょうど、 find コマンドでファイルサイズを指定した場合と同じような結果になります。

find /Users/hayato/Desktop -type f -size +2M

ここでは単純にサイズとファイル名を標準出力に返していますが、対象のファイルそれぞれに対して特定の処理を行いたい場合などは print 文の前後を必要な処理に差し替えるとよいものと思います。

以上です。

例えば、コマンドライン引数をかんたんに扱うための標準ライブラリ argparse といっしょに使うともう少し汎用性の高いスクリプトを作ることができます。興味のある方は次のスニペットもよろしければ参考にしてみてください。