macosautomationapplescriptautomator

How to make Folder Action to watch a folder and if it sees 2+ files with same filename and diff ext, create new folder and move those files in folder


I've been searching for weeks and have been unsucessful on finding a way on my Mac running Ventura to help solve this wish.

I have a lot of files that have the same file name and are saved with different extensions and all exist in the same folder. I am looking for a script to use as a folder action that will do the following.

  1. Watch a folder and use it as a drop zone with a folder action powered by a script.
  2. If the folder sees 2 or more files with the same file name, create a subfolder inside of the working folder, and subsequently;
  3. Move files that have 2 or more with the same name but different extensions into the newly created subfolder.

Example;

Watched Folder Location is in my home folder named "Work".

Example Print.ai
Example Print.mkv
Example Print.jpg
Example Print.txt
Weird Logo 3454.psd
Weird Logo 3454.ai
Weird Logo 3454.png
Weird Logo 3454.gif
Green Bird.png
Green Bird.jpg
Lizard Jumping.mkv

Ideally, it would return the following results if run as a folder action on the folder "work" where all of these items reside;

/users/blaine/work/Example Print/
Example Print.ai
Example Print.mkv
Example Print.jpg
Example Print.txt

/users/blaine/work/Weird Logo 3454/
Weird Logo 3454.psd
Weird Logo 3454.ai
Weird Logo 3454.png
Weird Logo 3454.gif

/users/blaine/work/Green Bird/
Green Bird.png
Green Bird.jpg

/users/blaine/work/Lizard Jumping.mkv

Which should look like this when the folder "work" is opened.

/users/blaine/work/Example Print/
/users/blaine/work/Weird Logo 3454/
/users/blaine/work/Green Bird/
/users/blaine/work/Lizard Jumping.mkv

Any ideas? I have managed to create a shortcut that allows me to run a "quick action" and I can manually highlight files when sorted and create new folder from selection and automatically name the new folder the same as the file name without the extension, but there are thousands which makes me believe there must be a better way. Any help is appreciated.

These are the closest threads I was able to find on this topic, but they're a little too different for me to dissect and make work.

https://stackoverflow.com/a/57465078/21894037

Create new folder from files name and move files


For Reference, this is the script I have currently turned into a quick-action or use as a folder action. It works great except for having to manually scan through usually around 10-20k files.

tell application "Finder"
    activate
    set selectedFiles to selection as alias list
    set containingFolder to container of (item 1 of selectedFiles) --as alias
    repeat with i from 1 to count of selectedFiles
        set foldersRef to (a reference to folders of containingFolder)
        set foldersRefItems to name of (contents of foldersRef)
        set thisItem to item i of selectedFiles
        set fileName to (text items 1 thru -5) of (name of thisItem as text) as string
        if fileName is not in foldersRefItems then
            move thisItem to (make new folder at containingFolder ¬
                with properties {name:fileName})
        else
            move thisItem to folder fileName of containingFolder
        end if
    end repeat
end tell

Solution

  • Try this. Added to hot (watch) folder file(s) will be moved into the hot folder's appropriate subfolder(s).

    on adding folder items to thisFolder after receiving these_items
        set thisFolderHFSPath to thisFolder as text -- this watch folder's HFS path
        tell application "Finder" to set allFiles to (files of folder (thisFolder as text)) as alias list
        -- get all basenames list
        set basenames to {}
        repeat with anItem in allFiles
            set end of basenames to my getBaseName(POSIX path of anItem)
        end repeat
        repeat with anItem in these_items
            set baseName to my getBaseName(POSIX path of anItem) -- baseName of file
            tell application "Finder"
                try
                    -- if the appropriate subfolder exists then sure the file should be moved in it
                    set subFolder to folder (thisFolderHFSPath & baseName)
                    try -- required try block here   
                        move file (anItem as text) to subFolder
                    end try
                on error -- if no appropriate subfolder, then 
                    set aCount to 0
                    repeat with b in basenames
                        if baseName is (contents of b) then set aCount to aCount + 1
                    end repeat
                    if aCount > 1 then -- the file should be moved if duplicate basename
                        set subFolder to make new folder at thisFolder with properties {name:baseName}
                        try -- required try block here   
                            move file (anItem as text) to subFolder
                        end try
                    end if
                end try
            end tell
        end repeat
    end adding folder items to
    
    on getBaseName(posixPath)
        set {ATID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "/"}
        if (posixPath ends with "/") then
            set baseName to text item -2 of posixPath
        else
            set baseName to text item -1 of posixPath
        end if
        if (baseName contains ".") then
            set AppleScript's text item delimiters to "."
            set baseName to text 1 thru text item -2 of baseName
        end if
        set AppleScript's text item delimiters to ATID
        return baseName
    end getBaseName