Hello – I’m looking for a solution to move 100+ files into their respective folder, based on matching the last 4 characters (not including the file extension) with the last 4 characters of the folder. (The folders names have the same last 4 characters as the file names.)
For example, I would move Filename-ABC1.png and Filename-ABC1.eps to “Foldername - ABC1” while at the same time moving Filename-DEF5.png and Filename-DEF5.eps to “Foldername - DEF5” and so on.
There are 50+ folders / 100+ files, and these names change based on each batch of files/folders.
While Hazel does such things, it would require the need to create many separate rules for each one.
This script does what you want but speed may be an issue. Also, it assumes that all of the destination folders are top-level folders in the same parent folder (viz. targetFolder). Both of these issues can be dealt with but it’s always best to start simple. It’s essential that you work with duplicate files/folders until everything is found to work properly.
on main()
set sourceFolder to (path to desktop as text) & "Source Folder"
set targetFolder to (path to desktop as text) & "Target Folder"
tell application "Finder"
set theFiles to every file in folder sourceFolder
set theFolders to every folder in the entire contents of folder targetFolder
end tell
set ATID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"."}
repeat with aFile in theFiles
set aFileBase to text 1 thru text item -2 of (aFile as text)
set aFileKey to text -4 thru -1 of aFileBase
repeat with aFolder in theFolders
if text -5 thru -2 of (aFolder as text) = aFileKey then
try
tell application "Finder" to move aFile to aFolder
exit repeat
on error
display dialog "The file " & quote & (name of aFile) & quote & " already exists"
exit repeat
end try
end if
end repeat
end repeat
set AppleScript's text item delimiters to ATID
end main
main()
Edit March 25, 2021. I edited this script to act recursively in setting the variable theFolders and to include some simple error notification. I also placed the script in a handler, which has a small technical advantage.
The following script addresses both of the possible issues with the above script. It uses System Events to make things move along more quickly and it uses ASObjC to recursively get all folders within the target folder. It should be noted that this script throws an error if a file already exists in the destination folder; some error correction should be added to deal with this.
use framework "Foundation"
use scripting additions
set sourceFolder to POSIX path of ((path to desktop as text) & "Source Folder")
set targetFolder to POSIX path of ((path to desktop as text) & "Target Folder")
tell application "System Events" to set theFiles to POSIX path of (every file in folder sourceFolder whose visible is true)
set theFolders to getFolders(targetFolder)
set ATID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"."}
repeat with aFile in theFiles
set aFileBase to text 1 thru text item -2 of aFile
set aFileKey to text -4 thru -1 of aFileBase
repeat with aFolder in theFolders
set aFolder to POSIX path of aFolder
if text -5 thru -2 of aFolder = aFileKey then
tell application "System Events" to move file aFile to folder aFolder
exit repeat
end if
end repeat
end repeat
set AppleScript's text item delimiters to ATID
on getFolders(theFolder)
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
set theFileManager to current application's NSFileManager's new()
set packageOption to current application's NSDirectoryEnumerationSkipsPackageDescendants
set hiddenOption to current application's NSDirectoryEnumerationSkipsHiddenFiles as integer
set folderContents to (theFileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:(packageOption + hiddenOption) errorHandler:(missing value))'s allObjects()
set thePredicate to current application's NSPredicate's predicateWithFormat:"pathExtension == ''"
set theFolders to folderContents's filteredArrayUsingPredicate:thePredicate
return folderContents as list
end getFolders