安全策の上に安全策を講じた、心配性のファイル名称変更AppleScriptです。
基本的にはファイルのリネームプログラムであり、Finder上で選択中のファイルについてリネームを行います。
ただし、ファイルのリネーム時に同じファイル名のファイルがすでに存在していて、普段であれば衝突回避のために子番号を振るなどの対処を行うところが、そういう対応が許されていないようなケースに直面しました。
同じフォルダ内にある3つの画像ファイルを、名称が衝突するような他の名称に変更するようなケースです。
1.jpg --> 2.jpg(すでに2.jpgが存在) 2.jpg --> 3.jpg(すでに3.jpgが存在) 3.jpg --> 1.jpg
少々、頭を抱えてしまいました。
そこで、テンポラリフォルダをファイル1つごとに作成し、テンポラリフォルダにファイルを移動。
1.jpg --> /temp/uuid0001/1.jpg
そのタコツボ的なテンポラリフォルダの中でリネームを実施。
/temp/uuid0001/1.jpg --> /temp/uuid0001/2.jpg
リネームしたファイルを元のフォルダに戻すというリネームルーチンを作成した次第です。もちろん、作成したテンポラリフォルダは削除しておきます。
/temp/uuid0001/2.jpg --> 2.jpg
最近はこのAppleScriptのように、ファイル操作処理はNSFileManagerで実行し、Finderには「選択中のファイルの情報を取得」ぐらいしか行わせていません。そのため、ファイル処理が従来よりもはるかに高速に行えて、ちょっと楽しいぐらいです。
数千ファイルのコピー(込み入ったルールに従いJANコードなどのデータを参照して名前を決定したり、フォルダ名を製品名で作成したりとか)が1・2秒というオーダーで終わってしまうのは、SSD上で処理しているせいもありますが、NSFileManager経由でのファイル処理を行っているおかげです(64bit化したCocoa Finderはとにかく処理が遅いのでAppleScriptからのファイル操作用に使うとダメ)。
AppleScript名:tempフォルダに移動しつつリネームして、終了後に元フォルダに戻す v2.scptd |
— Created 2018-08-14 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSUUID : a reference to current application’s NSUUID property NSString : a reference to current application’s NSString property NSFileManager : a reference to current application’s NSFileManager property tResList : {} property tFol : "" property newNameTemplate : "test_" set tResList to {} set tFol to POSIX path of (path to temporary items) tell application "Finder" set aSel to selection as alias list if aSel = {} then display notification "No Selection" return end if end tell –コピー元ファイルの親フォルダを求める(リネーム後に戻す) set origFol to POSIX path of (contents of first item of aSel) set origFolStr to ((NSString’s stringWithString:origFol)’s stringByDeletingLastPathComponent()) as string –一時フォルダに移動してリネーム set aCount to 1 repeat with i1 in aSel set j1 to POSIX path of (contents of i1) set newName to newNameTemplate & (aCount as string) set j1Res to renameSafely(j1, newName) of me set the end of tResList to (j1Res as string) set aCount to aCount + 1 end repeat –元のフォルダに戻して一時フォルダ削除 repeat with i2 in tResList set j2 to contents of i2 set j2Res to (my moveFileAt:j2 toFolder:origFolStr) set j2Res to deleteParentFol(j2) of me end repeat –安全なリネーム(個別のテンポラリフォルダに移動してリネーム) on renameSafely(aFile, newName) –set tFol to POSIX path of (path to temporary items) set aUUIDstr to ((NSUUID’s UUID()’s UUIDString()) as string) set aTmpFol to tFol & aUUIDstr set dRes to makeDirAbsolutely(aTmpFol) of me set mRes to my moveFileAt:aFile toFolder:aTmpFol set aStr to (NSString’s stringWithString:aFile) set newFullPath to aTmpFol & "/" & aStr’s lastPathComponent() set aExt to aStr’s pathExtension() set fRes to renameFileItem(newFullPath, newName) of me set renamedPath to aTmpFol & "/" & newName & "." & aExt return renamedPath end renameSafely –指定パスににフォルダを作成する on makeDirAbsolutely(dirStr) set fileManager to NSFileManager’s defaultManager() set aRes to fileManager’s createDirectoryAtPath:dirStr withIntermediateDirectories:true attributes:(missing value) |error|:(reference) copy aRes to {aFlag, aError} return aFlag as boolean end makeDirAbsolutely on moveFileAt:POSIXPath toFolder:folderPOSIXPath set POSIXPath to NSString’s stringWithString:POSIXPath set theName to POSIXPath’s lastPathComponent() set folderPOSIXPath to NSString’s stringWithString:folderPOSIXPath set theNewPath to folderPOSIXPath’s stringByAppendingPathComponent:theName set fileManager to NSFileManager’s defaultManager() set theResult to fileManager’s moveItemAtPath:POSIXPath toPath:theNewPath |error|:(missing value) return theNewPath end moveFileAt:toFolder: on renameFileItem(aPOSIXpath as string, newName as string) set theNSFileManager to NSFileManager’s defaultManager() set POSIXPathNSString to NSString’s stringWithString:(aPOSIXpath) –Make New File Path set anExtension to POSIXPathNSString’s pathExtension() set newPath to (POSIXPathNSString’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:newName)’s stringByAppendingPathExtension:anExtension –Rename if theNSFileManager’s fileExistsAtPath:newPath then return false else set theResult to theNSFileManager’s moveItemAtPath:POSIXPathNSString toPath:newPath |error|:(missing value) if (theResult as integer = 1) then return (newPath as string) else return false end if end if end renameFileItem on deleteParentFol(aPOSIX) set aStr to NSString’s stringWithString:aPOSIX set parentFol to aStr’s stringByDeletingLastPathComponent() set aRes to deleteItemAt(parentFol) of me return aRes end deleteParentFol on deleteItemAt(aPOSIX) set theNSFileManager to NSFileManager’s defaultManager() set theResult to theNSFileManager’s removeItemAtPath:(aPOSIX) |error|:(missing value) return (theResult as integer = 1) as boolean end deleteItemAt |
More from my site
(Visited 446 times, 1 visits today)