applescriptassetsautomatorfile-organization

(Applescript) Rename and Move / Organize Files to Subfolders


Edit: I have already created the subfolders beforehand using automator.

I am a designer that is currently designing for Android. I use Sketch App to export all my assets so that they will have equivalent suffixes (e.g. -xxxhdpi, -xxhdpi, -xhdpi, -hdpi, -mdpi).

example of files: see the screenshot

example of folders: see the screenshot

What I'm trying to do is to move all these assets to subfolders (/xxxhdpi, /xxhdpi, etc.) and trim their suffixes.

Having zero knowledge in programming/applescripting, I tried to use Automator. But I was stumbled upon its limitation for relative paths. After searching for a lot of resources (including Looking for an Applescript to find files and move them to different folder and Applescript: Create folders/subfolders and move multiple files). It's kinda confusing because I can't quite figure out what those lines are doing. But I came up with this

tell application "Finder"

    set assetsFolder to (target of front Finder window) as text
    do shell script "cd " & (quoted form of POSIX path of assetsFolder) & "; "
    set selectedItems to selection

    repeat with this_item in selectedItems
        if this_item's name contains "-xxxhdpi" then
            set the theName to this_item's name
            set the theSource to "-xxxhdpi"
            set the theReplacement to ""
            move this_item to folder "xxxhdpi" of folder assetsFolder
            set name of this_item to my replace(theName, theSource, theReplacement)
        end if
    end repeat

end tell

on replace(theString, theSource, theReplacement)
    set AppleScript's text item delimiters to theSource
    set theItems to every text item of theString
    set AppleScript's text item delimiters to theReplacement
    return theItems as Unicode text
end replace

I realize that this only works for "xxxhdpi" case because I want to test it first. In the later time, I would like for this script to have other cases to apply for the rest of suffixes (I'm sorry if my English is bad).

The script itself is working fine for renaming and moving. But I can't get them to work together.

Right now, the problem is within this two lines:

set name of this_item to my replace(theName, theSource, theReplacement)
move this_item to folder "xxxhdpi" of folder assetsFolder

Either the files are renamed, but failed to move, or the files are moved but failed to be renamed.

Also, I have tried to search for plugins to do this exact thing (organizing android assets) but I had no luck. Either I got help for writing this applescript, or someone will tell me an equivalent plugin that will do the job.

Thanks in advance


Solution

  • Try this, the script assumes that the name of the subfolder is always the portion between the (last) hyphen and the dot before the name extension and there is always at least one hyphen in the file name.

    The script uses the command line interface ditto which is able to create intermediate directories on-the-fly. It separates name and extension of each selected file and strips the subfolder name from the file name. It's not necessary to create the subfolders "manually".

    tell application "Finder"
        set selectedItems to selection
        if selectedItems is {} then return
        set parentFolder to POSIX path of (container of item 1 of selectedItems as text)
    end tell
    
    set {TID, text item delimiters} to {text item delimiters, "-"}
    repeat with anItem in selectedItems
        set {fileName, fileExtension} to splitNameExtension(anItem)
        tell text items of fileName to set {prefix, suffix} to {items 1 thru -2 as text, item -1}
        set newFilePath to quoted form of (parentFolder & suffix & "/" & prefix & fileExtension)
        set sourceFile to quoted form of POSIX path of (anItem as text)
        do shell script "/usr/bin/ditto " & sourceFile & space & newFilePath & "; /bin/rm " & sourceFile
    end repeat
    set text item delimiters to TID
    
    on splitNameExtension(aFile)
        set {name:fileName, name extension:fileExtension} to aFile
        if fileExtension is missing value then return {fileName, ""}
        return {text 1 thru ((count fileName) - (count fileExtension) - 1) of fileName, "." & fileExtension}
    end splitNameExtension