質問: ディレクトリ構造 ``` $ ls -1 cham-arayaminami-high/2020年02月23日01時02分.jpg 2020年02月24日01時02分.jpg 2020年02月26日01時02分.jpg 2020年02月27日01時02分.jpg ~ 2020年06月10日12時06分.jpg ``` 抜けている日付を前の日の画像を複製し、補完したいです。 また、Exif情報の撮影された日時(DateTimeOriginal)を前の日のものではなく補完後のものと合わせたいです。 抜けている日付は数日間あるものをあります。 目的が達成できれば、シェルスクリプトでもpythonでも構いません。 ネットでも探しても似たような記事すら検索にかからず困っております。 ご教授頂けたら嬉しいです。
回答: python版を作って見ました(file_comp.py)。 外部ツールとしてExiftoolを必要とします。 同じ日のファイルが2つ以上存在するとエラーになります。 ``` import argparse import pathlib import pandas as pd from shutil import copyfile FILENAME_FORMAT = "%Y年%m月%d日%H時%M分.jpg" def update_exif(filename, exif_datetime): import subprocess args = [ "exiftool", "-overwrite_original", "-DateTimeOriginal={}".format( exif_datetime.strftime("%Y:%m:%d %H:%M:%S") ), filename, ] subprocess.Popen(args, stdout=subprocess.DEVNULL) def main(): parser = argparse.ArgumentParser() parser.add_argument("dirname") args = parser.parse_args() # ファイルリストを作成 p = pathlib.Path(args.dirname) filenames = [] for pathname in p.iterdir(): try: pd.to_datetime(pathname.name, format=FILENAME_FORMAT) filenames.append(pathname.name) except ValueError: pass filenames.sort() # 日付をインデックスに持つDataFrameを作成 df = pd.DataFrame({"src_filename": filenames}) df["datetime"] = pd.to_datetime(filenames, format=FILENAME_FORMAT) df.index = pd.DatetimeIndex(df.datetime.dt.date) df.index.name = "date" # 1日でリサンプリング df = df.asfreq(freq="1D") # 存在しない日付は前の日のファイルを複製 df.src_filename.fillna(method="ffill", inplace=True) # EXIFに埋め込む時刻は日付+00:00:00 df["exif_datetime"] = df.datetime df.exif_datetime.fillna(df.index.to_series(), inplace=True) # 出力するファイル名を作成 df["dst_filename"] = df.exif_datetime.dt.strftime(FILENAME_FORMAT) df_target = df[df.datetime.isnull()] # デバッグ用 print(df_target[["src_filename", "dst_filename", "exif_datetime"]]) # 処理対象のみ抽出して複製 for _, row in df_target.iterrows(): src = p / row.src_filename dst = p / row.dst_filename copyfile(src, dst) update_exif(dst, row.exif_datetime) if __name__ == "__main__": main() ``` 実行は引数にディレクトリを渡します。 実行すると新たに作成したファイルの一覧が表示されます。 ``` $ tree cham-arayaminami-high/ cham-arayaminami-high/ ├── 2020年02月21日01時02分.jpg ├── 2020年02月23日02時02分.jpg └── 2020年03月01日01時02分.jpg $ python file_comp.py cham-arayaminami-high/ src_filename dst_filename exif_datetime date 2020-02-22 2020年02月21日01時02分.jpg 2020年02月22日00時00分.jpg 2020-02-22 2020-02-24 2020年02月23日02時02分.jpg 2020年02月24日00時00分.jpg 2020-02-24 2020-02-25 2020年02月23日02時02分.jpg 2020年02月25日00時00分.jpg 2020-02-25 2020-02-26 2020年02月23日02時02分.jpg 2020年02月26日00時00分.jpg 2020-02-26 2020-02-27 2020年02月23日02時02分.jpg 2020年02月27日00時00分.jpg 2020-02-27 2020-02-28 2020年02月23日02時02分.jpg 2020年02月28日00時00分.jpg 2020-02-28 2020-02-29 2020年02月23日02時02分.jpg 2020年02月29日00時00分.jpg 2020-02-29 $ tree cham-arayaminami-high/ cham-arayaminami-high/ ├── 2020年02月21日01時02分.jpg ├── 2020年02月22日00時00分.jpg ├── 2020年02月23日02時02分.jpg ├── 2020年02月24日00時00分.jpg ├── 2020年02月25日00時00分.jpg ├── 2020年02月26日00時00分.jpg ├── 2020年02月27日00時00分.jpg ├── 2020年02月28日00時00分.jpg ├── 2020年02月29日00時00分.jpg └── 2020年03月01日01時02分.jpg $ exiftool -n -DateTimeOriginal cham-arayaminami-high/*.jpg ======== cham-arayaminami-high/2020年02月21日01時02分.jpg Date/Time Original : 2020:06:10 14:35:34 ======== cham-arayaminami-high/2020年02月22日00時00分.jpg Date/Time Original : 2020:02:22 00:00:00 ======== cham-arayaminami-high/2020年02月23日02時02分.jpg Date/Time Original : 2020:06:10 14:35:34 ======== cham-arayaminami-high/2020年02月24日00時00分.jpg Date/Time Original : 2020:02:24 00:00:00 ======== cham-arayaminami-high/2020年02月25日00時00分.jpg Date/Time Original : 2020:02:25 00:00:00 ======== cham-arayaminami-high/2020年02月26日00時00分.jpg Date/Time Original : 2020:02:26 00:00:00 ======== cham-arayaminami-high/2020年02月27日00時00分.jpg Date/Time Original : 2020:02:27 00:00:00 ======== cham-arayaminami-high/2020年02月28日00時00分.jpg Date/Time Original : 2020:02:28 00:00:00 ======== cham-arayaminami-high/2020年02月29日00時00分.jpg Date/Time Original : 2020:02:29 00:00:00 ======== cham-arayaminami-high/2020年03月01日01時02分.jpg Date/Time Original : 2020:06:10 14:35:34 10 image files read ```