FileMakerメディア管理 実作編 Ver.3 日付の情報

日付ゲットのコード

AppleScript

AppleScriptで取得するのが手っ取り早いです。なぜかというとターミナルコマンドを使うとしても結局「AppleScriptを実行」で行うから、AppleScriptだけで完結したほうが効率良さげです。でも現実にはシェルスクリプトも使います。AppleScript難しくてよく判らないし、ターミナルコマンドの優れたコードもあるからです。

日付をゲットするスクリプトはシンプルで、ファイル属性からGetで日付を引っ張ってくるだけです。作成日なら get creation date of file パス 、変更日なら get modification date of file パス です。

個別に引っ張ってくるだけなら簡単ですが、希望としては「パス+作成日+変更日」の形で情報を頂きたいんです。この最終的な形を指定することを「フォーマット」と言うようです。出力フォーマットを好きに作れるでしょうか。作れます。どうしますか。こうします。

変数にテキストとして詰め込みます。

パスを thePath、作成日を cDate 変更日を mDate と、カッコいい名前の変数に仕込み、最後に theList というカッコいい名前の変数を使って中に詰め込みます。

set theList to "" & thePath & "+++"  & "+++" & cdate & "+++" & mdate

“+++” はセパレータのつもりです。あとでFileMakerで”+++”を改行に置換するんです。最初に “” があるのは、最初がパスだと文字列じゃない受け取り方をされてしまうようなので、まず空の文字を置いてそれに繋げる形にしました。

もう一つ希望があります。

ターミナルコマンドで pbcopy を知ってから世界が広がりました。AppleScript にも同じのありますか。あるみたいです。こうです。

set the clipboard to theList

これで変数 theList がクリップボードに入ります。FileMakerのフィールドにペーストして加工して各フィールドに振り分けます。

まとめるとこうなります。

set thePath to POSIX file "$POSIX"
tell application "Finder"
	set cDate to get creation date of file thePath
	set mDate to get modification date of file thePath
	set theList to "" & thePath & "+++" & cDate & "+++" & mDate
	set the clipboard to theList
end tell

これを「AppleScriptを実行」させるとあっという間に日付情報ゲット成功。もちろん使用前に”$POSIX”をそのレコードのPOSIXに置換してからですよ。

受信した電波もとい受信したデータは「パス+++作成日+++変更日」となっていますから、+++ を改行に置き換えて「1行目がパス、2行目が作成日、3行目が変更日」ということで、日付フィールドに2行目、3行目を転記します。

AppleScriptが持ってくる日付を整形

ただしそのままではいけません。日付がフォーマットされてしまってるんです。2021年9月2日 木曜日 みたいになってます。これをFMのタイムスタンプに変換します。変換する計算式は、後ほどどこかに書きました(何その時系列が変な文章)

話戻って、この theList の最後に return を付け足して、さらに repeat with 何とかかんとかと組み合わせると、ループでフォルダ内アイテムを一括処理できたりします。ちょっと試そうとしましたが実力が伴わず頓挫しました。

一括処理はターミナルにお任せしましょう。

ターミナルコマンド

ターミナルコマンドで日付をゲットする方法はいろいろあります。フォルダ内のアイテム一括とか、フォルダ内のフォルダも含めてすべて網羅とか、やりたい事柄は複雑です。

ls

最初はリストを作るlsに期待しました。フォルダ内のファイルのみ、フォルダ内のフォルダも含む、いろいろなリストの作り方が柔軟にできそうだったからです。

でも出力フォーマットをカスタムする方法が判らなかった。さらに、作成日と変更日を両方取得することもできなかった。ウンザリするほどいろいろ試した結果、lsを却下しました。

stat

stat については stat で日付をゲット – ステイタスコマンド にすでに書きました。

stat で日付をゲット – ステイタスコマンド

ファイル属性の情報を取得するにはこいつが最適っぽいです。出力も自由自在。先ほどの AppleScript と同じフォーマットにも仕上げられます。同じフォーマットに仕上げるのはとても重要です。

statでは日付もフォーマットできます。でもフォーマットせずに、UNIXタイムスタンプのままゲットしたほうが後で都合がいいです。フォーマットされてしまったものをFileMakerのタイムスタンプに変換するは困難ですが、生の数字をFMタイムスタンプに変換することは容易です。変換する計算式はいろんな賢人さまたちがネットに上げていらっしゃいます。ここでも、後ほどどこかに書きました(また時系列がおかしな文章書きやがって)

話戻って、しかしstatはリスト機能がないので、フォルダ内のアイテムをどのように取得したいかによっていきなり複雑化してきます。

lsでリストを作ってそれをstatで処理するという二段構えも考えましたが、複雑さに拍車がかかるだけで手に負えませんでした。

この時点で、あれこれ複数コードを作りまくり試行錯誤を100万回繰り返し、そしてどれも面倒が過ぎてやさぐれて放棄しました。

「もう駄目だ」と矢吹ジョーのようにリングでうなだれます。「フォルダ内フォルダを選択に含めるとか、もうそういうの一切禁止にしようか」とすら思い始めました。

find

そんな中ぴかりと光が差し、天の一角がめくれて神様が顔を出し「findでやればええよ」と教えてくれました。

ループにループを重ねる複合ループでサブフォルダを探っていく地獄に陥っていた矢吹Booは、ここで初めて find についてちょっと調べて、その結果最も理想に近い挙動がそこにあることを知ります。

ぶりっとパスを指定して find して「ファイル限定」ってやれば望みのファイルリストが返って来るではありませんか。サブフォルダを含む含まないも簡単に切り替えられて、あっという間に目的のリストが作成されます。

100万回の試行錯誤は何だったのか。find 最高。

find リファレンス

基本はこう書きます。パス(フォルダ)を書くと、そのフォルダ内を検索しますね。

find パス

オプションは、-type f がファイルのみ。除外は -not で、名前の最初が「 . 」を除外するときは -not -name “.*”  こう書くといいですね。「ファイルである」「名前が.で始まらない」あとは -maxdepth 1が「階層1個分のみ」だからフォルダ内アイテムに限定したいときに付け足します。より詳しいフィルタを駆使することで自由自在にファイルを探せますが、ここではややこしいことに踏み込みません。

find と stat を繋げた最強コード

find で見つけたファイルに対してコマンドを実行できます。これがカッコいいところです。find に stat を実行してもらいましょう。-exec と書いてその後ろにコマンドを書きます。

find $POSIX -type f -not -name ".*" -exec stat -f "%N+++%B+++%m" {} +

-exec の後ろのコマンドは stat -f “%N+++%B+++%m” です。 statで「パス+++作成日+++変更日」のフォーマットを返してくれるよう指令しています。
-f  は「次のフォーマットで返せよな」と命じるオプションです。

コマンドの後ろに謎の {} + がありますが、必要な措置だそうです。ファイルを一つずつ処理するときは {}、まとめて処理するときは {} + と書くとか何とか。まったく意味わかりませんが必要なので書いてます。「 | 」 みたいなものなのでしょうか。

このコマンドにさらに「 | 」でコマンドを追加していきます。sort と、それから最後に肝心要の pbcopy です。

find $POSIX -type f -not -name ".*" -exec stat -f "%N+++%B+++%m" {} + | sort | pbcopy
find $POSIX -type f -maxdepth 1 -not -name ".*" -exec stat -f "%N+++%B+++%m" {} + | sort | pbcopy

これで思いっきり希望通りの結果が得られました。即ち、$POSIXにフォルダパスを代入するとフォルダ以下の全ファイルが「パス+++作成日+++変更日」のリストとなって返ってきます。下段は階層を指定したフォルダに限定します。

AppleScript で ターミナルコマンドを実行させる

さてコマンドが決定しました。これをFileMakerから実行させます。「AppleScriptを実行」スクリプトステップを使いますね。上で作ったややこしいコマンドをAppleScriptで実行できる形にしなければなりません。

これまですでに書いてきました。

FileMakerからターミナルコマンドを送り込む二つの方法

AppleScriptから実行させるコマンドのパスにスペースがあるとエラーになる問題を解決

ターミナルにコピペで送るのが簡単ですがウインドウがチラチラするので、ここはいちびって do script にチャレンジします。 ※ いちびる = 調子に乗る カッコつける

do scriptの難しいところは、パスや引数が含まれる場合です。ちょっと前まではまったく手も足も出ませんでしたが今はちょっぴり知恵がつきました。

tell application "Terminal"
	set thePath to quoted form of "$POSIX"
	do script $Command
end tell

パスは変数に収めてダブルクォーテーションで括ります。変数は ” ” であるところを ‘ ‘ にします。送り込むコマンドはこうなります。

"find " & thePath & " -type f -not -name '.*' -exec stat -f '%N+++%B+++%m' {} + " & " | sort | pbcopy"

AppleScript全体ではこうですね。

tell application "Terminal"
	set thePath to quoted form of "フォルダパス"
	do script "find " & thePath & " -type f -not -name '.*' -exec stat -f '%N+++%B+++%m' {} + " & " | sort | pbcopy"
end tell

フォルダパスに注意です。最後スラッシュで終わりません。

このAppleScriptを実行させることで、フォルダ内アイテムの「パス+++作成日+++変更日」のリストが一気に取得できます。

すごいぜおれ。よく育った。

FileMaker Pro

Download FM_MediaDB_Ver3_5.zip

実作ファイルV3 ご自由にお持ち帰りください

次はここで作成したコードを手際よく実行できる仕組みをDB内部に組み入れた話です。

FMでメディア管理 実作編 Ver.3 日付の情報
次のページ: コマンドツールを便利に使う余計な仕組み