フォルダの変更日付を内包するファイルに合わせて変更するFileMaker書類を作ってみました。
フォルダの日付を修正する
Finder で日付を頼りにしていると時々裏切られることがあります。OSが勝手にフォルダの変更日付を変えてしまうこともあるし、iCloud Drive では問答無用で日付が改変され悲惨なことになります。
iCloud 日付の悪夢
iCloud Drive にフォルダを置くと、置いた日時が変更日付にされてしまいます。長年使っていれば経年の蓄積のため気にならなくなることもありますが、例えばフォルダを置き直したりすると、その瞬間にフォルダ変更日が本日その時に変更されてしまい無茶苦茶になります。階層の奥底に至るまですべてのフォルダの日付が本日になってしまうというのは、これはもう悪夢ですね。
iCloud Drive に重要なフォルダを置いてはいけないという理由の一つがこのためです。日付を改変されたくない大事なフォルダを、iCloudDrive には絶対に預けてはいけません。
フォルダの変更日付を修正したい
フォルダの変更日が変えられてしまうと変更日ソートが出来なくなりますし、検索も使えません。そういうのがどうでもいいフォルダもありますが大事な場合もあります。
うっかり変えられてしまった階層が深い百個のフォルダ日付を半泣きで手動修正したこともあります。あんな辛いのは二度とごめんだ。自動化したい。でもどうやればいいのか見当もつかない。そんな人生でしたが少し目処が立ったのです。ファイルメーカーで作りました。
FileMakerでフォルダ変更日付の修正
AppleScript や UNIXコマンド、Automator、すべて難易度が高く目標としているような処理をタタタッとプログラミングすることなど普通の人間には到底不可能です。フォルダを読み込むだけであとはすべて自動で日付を修正してくれる夢のシステム、そんな夢を叶えてくれるツールがあります。そう、ファイルメーカーならね。何を言ってるんだか。
概要
修正の概要は、フォルダが内包するファイルやフォルダの中で最も新しい日付をフォルダの変更日にセットします。この方針が絶対であるとは申しませんがそうしています。
iCloud Drive では時々フォルダの作成日を「1970/01/01」にしてしまうこともありますが、現時点では作成日ではなく変更日のみの修正に留めています。
ダウンロード
フォルダの変更日付を勝手に変えられて半泣きになっている私以外の皆様のためにも、出来上がったファイルをここに置いてシェアしますね。
- FileMaker Pro v19 ファイルです
- Mac専用です
- コマンド stat や setfile を使用しますので、Xcode、DeveloperTool がインストール済みであることが前提です
- このファイルを信頼しきってはいけません。十分なテストを行い、安全性を確かめてください。いかなる事故が発生しても当方では責任を負いません。
使い方
「フォルダ選択」をクリックしてダイアログで目的のフォルダを指定します。すると内包するファイルやフォルダが階層以下すべてリストされます。
または直接入力欄にパス(POSIX)を記入します。直接記入した場合は「リスト化」ボタンが現れるのでクリックしてリストを作ります。
あとは「調整する」ボタンで勝手に全てのフォルダを調整します。
どう調整されるのか
フォルダ内のファイルやフォルダのうち、新しい日付をフォルダの変更日付としてセットします。ファイルは触りません。フォルダの変更日のみです。
「内包するファイルやフォルダのうち、最も新しい日付をフォルダの変更日としてセットする」ことを十分に理解してください。「それでは駄目なんだよ」という考えもあるでしょう。その場合、スクリプトを改造してマイルールで作り直してください。
自動化の仕組みなどを以下に記していきます。仕組みなんかどうでもいい人はここまでで十分でございます。
ファイルメーカーで自動化書類を作る
このブログの各所でお馴染み、自動化するならFileMakerとCodeRunです。ターミナルやAppleScriptでプログラムを書いて自動化するような高度なことが全くできない雑魚には最適な自動化装置です。CodeRun については該当記事をご覧ください。
CodeRun
当初、というか自分用に完成させたものは CodeRun でコマンドを実行させるので作るのも管理も比較的楽にいけました。この記事でシェアするために CodeRun と接続せずに使えるよう、内部にCodeRun的な仕組みを含めました。
強引なスクリプト
さて日付調整の仕組みをざっくり解説しますと、フォルダ内のアイテムをすべてレコード化して、最も深い階層から順に処理します。
フォルダ・ファイルの情報リストを作成する
まず目的のフォルダを選択して find と stat でファイル・フォルダのパスと日付を網羅したリストを作ります。
find '<POSIX>' -not -name '.*' -exec stat -f '%N, %T, %B, %m' {} + | pbcopy /*( <POSIX> は目的フォルダのパス)*/
このコマンドをAppleScriptで実行させるため、do shell script 化します。
do shell script "find '<POSIX>' -not -name '.*' -exec stat -f '%N+++%T+++%B+++%m' {} + | LANG=ja_JP.UTF-8 pbcopy &"
これをテンプレフィールドに置いておき、実行前に<POSIX>を実際のposixに置換します。
ところでなぜ find と stat なのか。ls では駄目なのか。それは、find を使うと全ての階層を含む上にフォルダ・ファイルの区別なく網羅できるからです。あと、ls では少なくとも作成日と変更日を両方同時にゲットできません。
そんなわけで、find ではフォルダ内の階層全て、ファイルとフォルダの区別なく全網羅でリストをゲットします。続いて、stat がファイルとフォルダの区別と日付をゲットしてくれます。
結果はクリップボードにありますから結果フィールドにペーストしてから分解・レコード化します。受け取った情報は「パス」「ファイルかフォルダかのType」「作成日」「変更日」です。
UNIX timestampを変換したり、”/” から階層数を得るなど小さな処理を済ませ、レコード化を完成させます。
変更日を変更するコマンド
変更日を変えるコマンドはこうです。日付の書式が特殊なので変換が必要です。
setfile -m '<TIMESTAMP>' '<POSIX>' // <TIMESTAMP> は mm/dd/yyyy HH:MM:SS の書式 <POSIX> は目的フォルダのパス
FileMakerのループを使って最下層から順に最大日付をゲットして階層一つ上のフォルダの変更日付に setfile で反映させます。このループはちょっとだけ複雑ですが、複雑なだけでやってることは単純です。
最初に最下層を処理
まず最下層を絞り込みます。想定されるのはファイルまたはフォルダまたは両方がある状況です。最下層にもしフォルダがあれば中身は空です(だって最下層ですからね)よって、最下層にフォルダを見つければまずそのフォルダの変更日付を作成日に合わせます。この処理で、最下層にあるファイルまたはフォルダの変更日付がすべて正しく設定されているという前提を作り出せました。次からは階層を一つ昇り、繰り返し処理します。
繰り返しの処理
階層の一つ上のフォルダを絞り込みます。ループでその階層のフォルダを一個ずつ処理していきましょう。まずそのフォルダの中身を抽出します。そこにフォルダがあれば、そのフォルダが内包するファイルやフォルダを検索し、変更日付の最大値をゲットして変数に保存、再びフォルダに戻りその日付を変更日付にセットします。
こうして階層内すべてのフォルダの変更日付が修正されたら、階層ひとつ上に行き、同じようにフォルダを検索し内包するファイルやフォルダを検索し日付をゲットしてフォルダ変更日にセット、これを繰り返し階層が0つまり最初に指定したトップのフォルダになれば終了です。
ファイルメーカーのループを使ったこのスクリプトで、何階層あろうがフォルダやファイルがいくつあろうが全部自動でいけます。
テスト
そんなことで、フォルダの変更日をその中身の日付に合わせる調整自動化ファイルでした。これをいきなり大事なオリジナルフォルダで使おうと思ってはいけません。作者はプログラマーでもFMプロフェッショナルでもありません。ただの雑魚です。
テストをするときは何かフォルダを複製して、そうですね、iCloud Drive に放り込んでください。すると、内包するすべてのフォルダ変更日が本日この時に変更されてしまいます。再び iCloud から取り出して、このFileMaker 書類で修正を試してみてください。
しつこいですが、決して「変えられた日付を元に戻す」ではなく、「内包するアイテムの最新日付に合わせる」処理であることを忘れないでくださいね。
十分にいろいろ想定したつもりですが、自分で使っていた完成品(CodeRunと接続する仕組みの別ファイル)を、バタバタっとアップ用に作り変えた際のミスもあるかもしれませんのでお気をつけを。
また、知恵のある方は想定される他の状況を思いついたり、もっと効率の良いやり方を編み出したりされるかもしれません。もしお気づきのことがあれば助言をお願いします。
[追記] 「 ‘ 」 のエスケープについて
フォルダ名に「 ‘ 」が含まれていた場合、上手く do script できません。たぶん、できないと思います。「 ‘ 」のエスケープ処理の方法を知らなかったからですが、後にちょっと知りました。
以下に関連の投稿があります。
FileMaker CodeManager シングルクォートの改善
これを参考にして、codeRun の置換計算部分を修正してくだされば幸いですが・・どこを触ればいいのか分かりにくいですよね。すいません。とりあえずフォルダ名に「 ‘ 」が含まれていれば上手くいかないかもしれない、と認識しといてください。