仕事でNode.jsをガリガリ書いた。パス名とかであれこれ悩みつつ学んだので、何か今のテンションなら行ける!と画像ファイル整理用のスクリプトを書いてみた。
SynologyのNASにはNode.jsがあるのだけどバージョンが4でちょっと古い。8.9.4を入れるのも面倒。
結局、PHPで書いた。
何回かテストしながら書き上げたのがこれ。DropboxのCamera Uploadsに自動で入ってくる画像はファイル名が日付になっているので、それをそのままファイル名にしている。
<?php foreach(glob('*.jpg') as $filename){ var_dump($filename); $pattern = '/([0-9]{4}).([0-9]{2}).([0-9]{2}) [0-9]{2}.[0-9]{2}.[0-9]{2}.jpg/'; $replacement = '$1$2$3/'; $dirname = preg_replace($pattern, $replacement, $filename); var_dump($dirname); if(!is_dir($dirname)){ mkdir($dirname,0777,true); } $newname = preg_replace($pattern, $replacement.$filename, $filename); var_dump($newname); rename($filename, $newname); }
動くことは動いたんだけど、Synology の方でどうやらファイル変更がかかるのに時間がかかるみたい。いったんqueに入れて順番に処理していくのかな。1か月分の画像を移動するのにのんびり5分くらいはかかりそう。Dropboxと連携してるせいで遅いのかなー。
しかしDSMのタスクスケジューラに入れておけば夜のうちに勝手にリネームしてくれるわけで、毎晩やるようになればたいした時間もかかるまい。しめしめ。
いくつかポイントなど。
glob
初めはglobだけで正規表現使わずになんとかなるかと思ったんだけど、繰り返しが使えないのが我慢ならぬ。
正規表現置換
最初、"Unknown modifier"というWarningが出て「あれ、何かエスケープし忘れたっけ?」と思ったら違った。
In PHP, a regular expression needs to be enclosed within a pair of delimiters. A delimiter can be any non-alphanumeric, non-backslash, non-whitespace character; /, #, ~ are the most commonly used ones. Note that it is also possible to use bracket style delimiters where the opening and closing brackets are the starting and ending delimiter, i.e., [pattern_goes_here] etc. are all valid.
--via php - Warning: preg_replace(): Unknown modifier ']' - Stack Overflow
PHPにおける正規表現は「デリミタで囲むこと」とある。/などを使うのが一般的、だそうだ。よくわからんがそうしたら動いた。
後方参照と呼ばれる「検索文字列の一部を置換に使う」のは\1, \2...でいいみたい。$1使う場合もあるみたいだけど、PHPでは\1らしい。
文字クラス外で、バックスラッシュに続いて 1 以上の数値(複数桁可) を記述したものは、パターン中のより前方(すなわち左)にある キャプチャ用サブパターンに対する後方参照 (back reference) です。
--via PHP: 後方参照 - Manual
rename
どうも融通が利かないの。
- ディレクトリがあるかどうか確認
- なかったらmkdir
- renameで移動
という手順を踏む必要があるみたい。このくらい一行でさらっと書けてもよさそうなもんだが、ファイルシステム向きの設計じゃないのかな。
タスクスケジューラ
ディレクトリ名にスペースがあるとパスが切れちゃうみたい。ダブルクォーテーションで囲むとよさげ。
コマンドラインからだとどちらも動く。
php "/volume1/homes/{usr_name}/hoge fuga/photo.php" php "/var/services/homes/{usr_name}/hoge fuga/photo.php"
それでもPermissionがどうのこうのいうので、sudo使ってやった。
タスクスケジューラではrootユーザーにしたらいいのかなー。実行しても反応が薄いので、動いているのかどうかよくわからん……。
結局
結局、Synologyのタスクスケジューラが難物で、自動実行してくれず、週に一度くらい、MacのコンソールからPHPに渡して実行している。幸い、Finder代替として使用しているPathFinderは右クリックからコンソールを起動できるので、手作業よりは、だいぶ楽になった。