2
\$\begingroup\$

I'm new at scripting, but I thought it would be handy to have a script that would change the extensions of selected files in Finder. I run this script from an automator service so that batch changing extensions in Finder is always just a right click away.

So far, it has worked as I expect, but since this is one of my first scripts, my question is: is there a cleaner way to obtain this functionality? Can anyone point out a case I haven't thought of in which this would fail?

What this script does:

  • Asks the user for a new extension.
  • Adds the new extension to any files that don't already have one.
  • Changes the extension in other files even if it's a hidden file or has multiple points.

A test case that does not function correctly:

  • The selected file's name has multiple points, but no extension. Here, my script replaces the text after the last point with the new extension.

Here's the code:

# Ask user for new extension to be used
set newExt to the text returned of (display dialog "Enter extension:" default answer "Do not include first point")


tell application "Finder"

    # Make a list of the selected files in Finder
    set selFiles to selection as list

    set TID to AppleScript's text item delimiters

    repeat with eachFile in selFiles

        # Make a text item list of the file name delimited by points
        set filePath to eachFile as text
        set AppleScript's text item delimiters to {":"}
        set fileName to last text item of filePath
        set AppleScript's text item delimiters to {"."}
        set textItems to text items of fileName

        # Handle case where there is currently no extension, but one should be added.
        if number of textItems is 1 then
            set name of eachFile to fileName & "." & newExt

        # If an extension does already exist...
        else

            set newName to ""
            set numItems to number of items in textItems
            set n to 1

            repeat numItems times

                # If the current text item is not the extension, add it & "." to the new file name.  No need here to consider the last text item since it's the old extension and we want to get rid of it.
                if n is not numItems then
                    set newName to newName & item n in textItems & "."
                    set n to n + 1
                end if

            end repeat

            set name of eachFile to newName & newExt

        end if

    end repeat

    # Is this line necessary?  I just saw it at the end of someone else's script that had earlier set TID to AppleScript's text item delimiters.
    set AppleScript's text item delimiters to TID

end tell

Feel free to use this if it would be useful for you.

\$\endgroup\$
2
  • \$\begingroup\$ I have rolled back Rev 3 to 2. Please explain your improvement by posting an answer to your own question. \$\endgroup\$ Feb 4, 2016 at 19:25
  • \$\begingroup\$ Thanks 200_success. I posted the updated script as an answer. I suppose it's easier to follow the evolution of the script this way? \$\endgroup\$ Feb 5, 2016 at 11:13

2 Answers 2

1
\$\begingroup\$

Breaking file paths into file names and file extensions is unneeded when properties exist to access these elements directly, in this case the name extension property.

set newExt to the text returned of (display dialog "Enter extension:" default answer "Do not include first point")

tell application "Finder"
    set selFiles to selection
    repeat with eachFile in selFiles
        set name extension of eachFile to newExt
    end repeat
end tell
\$\endgroup\$
2
  • \$\begingroup\$ Much simpler, and I was not aware of the extension property, so thank you for that. However, this does not replace unusual extensions that are not recognized by the system. \$\endgroup\$ Feb 5, 2016 at 11:12
  • \$\begingroup\$ I can confirm that, I was trying to change a .yaml extension to .txt and was throwing a stack overflow error. Log the name extension of the file to see what the system thought it was dealing with and received this error: Can’t get name extension of alias \"Macintosh HD:Users:xxxxxxxx:Desktop:prebidServerBidders:client.yaml \$\endgroup\$
    – PruitIgoe
    Nov 19, 2020 at 14:39
0
\$\begingroup\$

I updated the script to handle the failed test case (sort of, at the users discretion). Previously, when I ran it on file names with multiple points and no pre-existing extension, text in the filename following the last point would be lost. As a workaround, I added a button to the dialog that forces the new extension to be appended to the full filename. This mode could be useful if you want to keep a record of the previous extension in the filename as well.

Updated code:

# Ask user for new extension to be used
set dRecord to (display dialog "Enter extension:" default answer "Do not include first extension point" buttons {"Cancel", "Force Appendation", "OK"} default button "OK" cancel button "Cancel")

set newExt to text returned of dRecord
set dButton to button returned of dRecord

# To change the extension in the default manner
if dButton = "OK" then

    tell application "Finder"

        # Make a list of the selected files in Finder
        set selFiles to selection as list

        set TID to AppleScript's text item delimiters

        repeat with eachFile in selFiles

            # Make a text item list of the file name delimited by points
            set filePath to eachFile as text
            set AppleScript's text item delimiters to {":"}
            set fileName to last text item of filePath
            set AppleScript's text item delimiters to {"."}
            set textItems to text items of fileName

            # Handle case where there is currently no extension, but one should be added.
            if number of textItems is 1 then
                set name of eachFile to fileName & "." & newExt

                # If an extension does already exist...
            else

                set newName to ""
                set numItems to number of items in textItems
                set n to 1

                repeat numItems times

                    # If the current text item is not the extension, add it & "." to the new file name.  No need here to consider the last text item since it's the old extension and we want to get rid of it.
                    if n is not numItems then
                        set newName to newName & item n in textItems & "."
                        set n to n + 1
                    end if

                end repeat

                set name of eachFile to newName & newExt

            end if

        end repeat

        # Is this line necessary?  I just saw it at the end of someone else's script that had earlier set TID to AppleScript's text item delimiters.
        set AppleScript's text item delimiters to TID

    end tell

# To strictly append the new extension to the current filename  
else if dButton = "Force Appendation" then

    tell application "Finder"

        # Make a list of the selected files in Finder
        set selFiles to selection as list

        repeat with eachFile in selFiles

            set eachName to name of eachFile as text

            set name of eachFile to eachName & "." & newExt

        end repeat

    end tell

end if
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.