🐍

macOS で撮ったスクリーンショットを自動で月別または日別のディレクトリに振り分けるようにしてみた

2021/04/01に公開
2

macOS でスクリーンショットを撮ると、指定したディレクトリ (デフォルトではデスクトップ) に日付や時間を含んだファイル名で保存されます。ただ、放っておくとどんどん溜まっていって目的のファイルを見つけにくくなります。今回は、スクリーンショットを取得した際に、自動で月別または日別のディレクトリに分けて保存されるようにしてみたという話です。

概要

何もせずにスクリーンショットを撮り続けると、下記のような形で保存先のディレクトリ直下に画像ファイルが大量にあるという状態になります。

$ tree .
/your/path/
├── sc__2021-01-01_132830.png
├── sc__2021-01-22_222346.png
├── sc__2021-02-11_163716.png
├── sc__2021-02-16_140132.png
├── sc__2021-02-16_190945.png
├── sc__2021-02-16_191009.png
├── sc__2021-02-16_191703.png
├── sc__2021-02-16_192223.png
├── sc__2021-02-22_131052.png
├── sc__2021-02-22_134907.png
├── sc__2021-03-01_101256.png
├── sc__2021-03-01_195937.png
├── sc__2021-03-01_200003.png
├── sc__2021-03-01_200033.png
├── sc__2021-03-01_214710.png
├── sc__2021-03-03_183331.png
├── sc__2021-03-03_183737.png
├── sc__2021-03-05_213054.png
├── sc__2021-03-05_213957.png
├── sc__2021-03-07_130956.png
├── sc__2021-03-07_151354.png
├── sc__2021-03-07_151433.png
├── sc__2021-03-07_151650.png
├── sc__2021-03-07_151715.png
├── sc__2021-03-07_151746.png
├── sc__2021-03-07_151749.png
├── sc__2021-03-07_152524.png
├── sc__2021-03-07_152639.png
├── sc__2021-03-07_153639.png
└── sc__2021-03-07_153639_2.png

これを、自動で次のような形で振り分けるようにするのが今回の内容です。

$ tree .
/your/path/
└── 2021
    ├── 01
    │   ├── sc__2021-01-01_132830.png
    │   └── sc__2021-01-22_222346.png
    ├── 02
    │   ├── sc__2021-02-11_163716.png
    │   ├── sc__2021-02-16_140132.png
    │   ├── sc__2021-02-16_190945.png
    │   ├── sc__2021-02-16_191009.png
    │   ├── sc__2021-02-16_191703.png
    │   ├── sc__2021-02-16_192223.png
    │   ├── sc__2021-02-22_131052.png
    │   └── sc__2021-02-22_134907.png
    └── 03
        ├── sc__2021-03-01_101256.png
        ├── sc__2021-03-01_195937.png
        ├── sc__2021-03-01_200003.png
        ├── sc__2021-03-01_200033.png
        ├── sc__2021-03-01_214710.png
        ├── sc__2021-03-03_183331.png
        ├── sc__2021-03-03_183737.png
        ├── sc__2021-03-05_213054.png
        ├── sc__2021-03-05_213957.png
        ├── sc__2021-03-07_130956.png
        ├── sc__2021-03-07_151354.png
        ├── sc__2021-03-07_151433.png
        ├── sc__2021-03-07_151650.png
        ├── sc__2021-03-07_151715.png
        ├── sc__2021-03-07_151746.png
        ├── sc__2021-03-07_151749.png
        ├── sc__2021-03-07_152524.png
        ├── sc__2021-03-07_152639.png
        ├── sc__2021-03-07_153639.png
        └── sc__2021-03-07_153639_2.png

ちなみに、 macOS でスクリーンショットを撮ると自動で付与されるファイル名には半角スペース やピリオド . が含まれるので、それが気持ち悪いという方は過去に書いたこちらの記事も参考にしてみてください。

Mac で撮ったスクリーンショットのファイル名に含まれる半角スペースを Automator でどうにかする - michimani.net

ちなみに今回紹介する方法では、上の記事で書いた処理も含んでいます。

やること

上の記事で紹介した内容と同じで、 macOS に入っている Automator を使用して自動振り分けを実現します。

スクリプトの実装

スクリプトは Python で書いてます。

追記

※スクリプトの一部に不備があったため修正いたしました。
 ご指摘いただいた 星影 さま、ありがとうございます 🙇

import glob
import os
import re

FILE_TYPE = 'png'
NEW_FILE_PATTERN = r'.*(\d{4})-(\d{2})-(\d{2})_\d{5,6}([^\/]+)?\.' + FILE_TYPE
SC_DIR = '/Users/hoge/Pictures/_ScreenCaptureTmp'
SC_OUT_DIR = '/Users/hoge/Pictures/ScreenCaptures'

DIR_TYPE = 'MONTH'  # "DAY" or "MONTH"


def get_screen_captures():
    # type: () -> list(str)
    return glob.glob(SC_DIR + '/*.' + FILE_TYPE)


def rename_file_path(filename):
    # type: (str) -> str
    """Rename file path.

        * replace half space to under score
        * remove period
        * replace "(N)" of "(N)" to "_N"

        Example:
           "sc 2020-03-05_21.39.57.png" -> "sc_2020-03-05_213957.png"
    """
    filename_tmp = filename.replace('.' + FILE_TYPE, '')
    filename_tmp = re.sub(
        r'( |\(|()', '_', re.sub(r'(\.|\)|))', '', filename_tmp))
    return filename_tmp + '.' + FILE_TYPE


def create_daily_directory(filename):
    # type: (str) -> str
    """Create daily directory from renamed file name if it does not exists.

        Example:
            If the file name is "sc_2020-03-05_213957.png",
            following directories will be created.

            SC_OUT_DIR/2020/03/05
    """
    daily_dir = SC_OUT_DIR + \
        re.sub(NEW_FILE_PATTERN, r'/\1/\2/\3', filename)
    if os.path.exists(daily_dir) is False:
        print('create directory ' + daily_dir)
        os.makedirs(daily_dir)

    return daily_dir


def create_monthly_directory(filename):
    # type: (str) -> str
    """Create monthly directory from renamed file name if it does not exists.

        Example:
            If the file name is "sc_2020-03-05_213957.png",
            following directories will be created.

            SC_OUT_DIR/2020/03
    """
    monthly_dir = SC_OUT_DIR + \
        re.sub(NEW_FILE_PATTERN, r'/\1/\2', filename)
    if os.path.exists(monthly_dir) is False:
        os.makedirs(monthly_dir)

    return monthly_dir


def move_file(old_path, new_path):
    # type: (str, str) -> ()
    os.rename(old_path, new_path)


if __name__ == '__main__':
    sc_list = get_screen_captures()
    if len(sc_list) == 0:
        print('There are no scren capure file.')
        exit

    for sc_file_path in sc_list:
        renamed_file_path = rename_file_path(sc_file_path)
        if DIR_TYPE == 'DAY':
            out_dir = create_daily_directory(renamed_file_path)
        else:
	    out_dir = create_monthly_directory(renamed_file_path)

        new_file_path = renamed_file_path.replace(SC_DIR, out_dir)
        move_file(sc_file_path, new_file_path)

michimani/organize_mac_screen_captures.py - gist

長いですが、使用する際に書き換えるのは冒頭のこの部分です。

SC_DIR = '/Users/hoge/Pictures/_ScreenCaptureTmp'
SC_OUT_DIR = '/Users/hoge/Pictures/ScreenCaptures'
DIR_TYPE = 'MONTH'  # "DAY" or "MONTH"
  • SC_DIR
    スクリーンショットを撮った際に画像ファイルが保存されるディレクトリを指定してください。デフォルトのままでデスクトップの場合は /Users/hoge/Desktop となります。 最後に / は不要です。

  • SC_OUT_DIR
    月別または日別に振り分けられた後の画像ファイルを保存するディレクトリを指定します。

  • DIR_TYPE
    月別に振り分ける場合は MONTH 、日別に振り分ける場合は DAY を指定します。それ以外の文字列を指定した場合は MONTH を指定したものとして処理されます。

SC_DIRSC_OUT_DIR は同じディレクトリを指定することも可能です。

スクリーンショットの設定で保存時の拡張子を変更している場合は FILE_TYPE の値を適宜変更してください。

上の記事で書いた通り、ファイル名に含まれる半角スペースとピリオドはそれぞれ置換、削除するようになっています。また、今回はそれに加えて丸括弧 () () も置換、削除するようにしています。 マルチディスプレイで作業しているときに画面全体のスクリーンショット (⌘ + Shift + 3) を撮ると、ファイル名の後ろに (1) のような形で番号がつきます。これも気持ち悪いので、 (N)_N に置換するようにしています。

これを適当な場所に保存します。今回は /Users/hoge/Projects/system/ に保存するとします。

Automator の設定

Automator では次の構成を作成します。

  1. フォルダアクションで、スクリーンショットの保存先ディレクトリ (SC_DIR で指定したディレクトリ) を指定。
  2. シェルスクリプトを実行 のところで、先ほど保存したスクリプトを実行するコマンドを記述。
  3. 処理終了通知の設定。

設定が完了するとこのような形になります。

あとは実際にスクリーンショットを撮ってみて、自動で振り分けられることを確かめます。

まとめ

macOS で撮ったスクリーンショットを自動で月別または日別のディレクトリに振り分けるようにしてみた話でした。普段から不要になったスクリーンショットを削除するなどしていればあまり恩恵は無いかもしれませんが、私のようにひたすら溜まっていくだけだという方はぜひ試してみてください。

Discussion

unsoluble_sugarunsoluble_sugar

有用なtipsの紹介ありがとうございます。
ぜひ活用させていただきたいと思います😊

スクリプトの挙動について気になった点がありましたので、コメントさせていただきます。

DIR_TYPE の分岐処理にて、create_daily_directorycreate_monthly_directory の呼び出しが逆になっている気がしました。

以下の形が正しいのではないかと思いましたが、いかがでしょうか?

if DIR_TYPE == 'DAY':
    out_dir = create_daily_directory(renamed_file_path)
else:
    out_dir = create_monthly_directory(renamed_file_path)
michimanimichimani

コメントありがとうございます!

ご指摘いただいたとおり、ここの呼び出しは逆ですね...失礼いたしました。
記事内と gist のスクリプトは修正いたします。

ご指摘いただき、ありがとうございました!