カレントディレクトリ配下のファイルの作成日と更新日を指定の日時に一括変更する Mac 専用シェルスクリプト

ニホンノエスイーの皆さん用。

カレントディレクトリ配下にあるファイルの、作成日時と更新日時を、それぞれ任意の日時に変更できるシェルスクリプトを作った。date コマンドのオプションの書式や、setfile コマンドを使用したりしていることから、Mac 専用の Bash スクリプトである。

#!/bin/bash

# Change created / updated date to the files in the current working directory

if [ "$(uname)" != "Darwin" ]; then
  echo 'This script is not supported on this OS.'
  exit 1
fi

function invalid_arguments_exit() {
  echo 'Invalid arguments.'
  exit 1
}

while getopts ":c:u:" OPT; do
  case "$OPT" in
    c)  CREATED_DATE="$OPTARG"
        ;;
    u)  UPDATED_DATE="$OPTARG"
        ;;
    \?) invalid_arguments_exit
        ;;
  esac
done

if [ -n "$CREATED_DATE" ]; then
  echo ''
  echo "Created Date : $CREATED_DATE"
  FORMATTED_CREATED_DATE=`date -j  -f "%Y-%m-%d %H:%M:%S" "$CREATED_DATE"  +"%m/%d/%Y %H:%M:%S"`
  echo "-> Formatted : $FORMATTED_CREATED_DATE"
  
  for file in `find . -maxdepth 1 -type f`; do
    echo "-> Execute : $file"
    setfile -d "$FORMATTED_CREATED_DATE" $file
  done
fi

if [ -n "$UPDATED_DATE" ]; then
  echo ''
  echo "Updated Date : $UPDATED_DATE"
  FORMATTED_UPDATED_DATE=`date -j  -f "%Y-%m-%d %H:%M:%S" "$UPDATED_DATE"  +"%Y%m%d%H%M.%S"`
  echo "-> Formatted : $FORMATTED_UPDATED_DATE"
  
  for file in `find . -maxdepth 1 -type f`; do
    echo "-> Execute : $file"
    touch -t "$FORMATTED_UPDATED_DATE" $file
  done
  
fi

echo ''
echo 'Finished.'

今回特に勉強したのは getopts コマンド。引数を解析するためのコマンドで、コマンド直後に書く「コマンド名」と「各種オプション」の理解が難しかった。

今回のコードだと、-c-u オプションそれぞれで値を受け取れるようにしてあり (c:u:)、それ以外のオプションが指定されたらワーニングを出すようにしている (先頭の :)。getopts コマンドを呼ぶ度に引数をシフトして処理するイメージで、オプションごとの値は $OPTARG という変数に都度格納される。だから while 文で getopts を回して、毎回 case で内容を判定している。

Mac におけるファイル作成日時は、setfile コマンドで変更できる。単純なコマンドなら以下のとおり。

$ setfile -d '12/24/2018 09:45:00' './仕様書.xlsx'

ファイルの更新日時touch コマンドで良い。

$ touch -t 201812311200.00 './仕様書.xlsx'

もし Windows で同じことをやりたければ、PowerShell で書くのが良さそう。