applescript remove spaces replace with underscore

I am running this Applescript in an applet and it works great other than the fact that it only changes HALF of the file names. Then if you run it again it does HALF of those then HALF again and so on. Anyone have any insight or a better way to accomplish the goal?


set defDel to AppleScript'stext item delimiters

tell application "Finder"

set theFolder to folder (choose folder)

repeat with thisItem in theFolder

set thename to name of thisItem

if thename contains " " then

set AppleScript'stext item delimiters to " "

set newname to text items of thename

set AppleScript'stext item delimiters to "_"

set name of thisItem to (newname as string)

set AppleScript'stext item delimiters to defDel

end if

end repeat

end tell

thanks in advance!

Posted on May 3, 2016 10:56 AM

Reply
4 replies

May 3, 2016 12:43 PM in response to thejrowe

Some heavy Applescripter will have to comment on this.

[ I'll wait a bit and if no one comes along, I'll search for someone. ]


mac $ mkdir checkitout
mac $ cd checkitout/
/Users/mac/checkitout
mac $ touch "abc abc"
mac $ touch "abc 123 abc 123"
mac $ touch "abc    abc"
mac $ touch abcdef
mac $ touch nothing



tell application "Finder"
    set theFolder to folder (choose folder)
    log "theFolder = " & theFolder

    repeat with thisItem in theFolder
        log "thisItem = " & thisItem
        set thename to name of thisItem
        log "thename = " & thename
        if thename contains " " then
            set newname to my alterString(thename, " ", "_")
            log "    newname = " & newname
            set name of thisItem to (newname as string)
        end if
    end repeat

end tell


on alterString(thisText, delim, replacement)
    set resultList to {}
    set {tid, my text item delimiters} to {my text item delimiters, delim}
    try
        set resultList to every text item of thisText
        set text item delimiters to replacement
        set resultString to resultList as string
        set my text item delimiters to tid
    on error
        set my text item delimiters to tid
    end try
    return resultString
end alterString



bug or feature ... notice how the renamed file is gotten again. Notice how item three has an underbar in it. It's an altered version from item # 2.


tell application "Finder"
    choose folder
        --> alias "Macintosh HD:Users:mac:checkitout copy:"
    get folder (alias "Macintosh HD:Users:mac:checkitout copy:")
        --> folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
    get folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "Macintosh HD:Users:mac:checkitout copy:"
    (*theFolder = Macintosh HD:Users:mac:checkitout copy:*)
    count folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> 5
    get item 1 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "Macintosh HD:Users:mac:checkitout copy:abc    abc"
    (*thisItem = Macintosh HD:Users:mac:checkitout copy:abc    abc*)
    get name of item 1 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "abc    abc"
    (*thename = abc    abc*)
    (*    newname = abc____abc*)
    set name of item 1 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk to "abc____abc"
        --> "abc____abc"
    get item 2 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "Macintosh HD:Users:mac:checkitout copy:abc abc"
    (*thisItem = Macintosh HD:Users:mac:checkitout copy:abc abc*)
    get name of item 2 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "abc abc"
    (*thename = abc abc*)
    (*    newname = abc_abc*)
    set name of item 2 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk to "abc_abc"
        --> "abc_abc"
    get item 3 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "Macintosh HD:Users:mac:checkitout copy:abc_abc"
    (*thisItem = Macintosh HD:Users:mac:checkitout copy:abc_abc*)
    get name of item 3 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "abc_abc"
    (*thename = abc_abc*)
    get item 4 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "Macintosh HD:Users:mac:checkitout copy:abcdef"
    (*thisItem = Macintosh HD:Users:mac:checkitout copy:abcdef*)
    get name of item 4 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "abcdef"
    (*thename = abcdef*)
    get item 5 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "Macintosh HD:Users:mac:checkitout copy:nothing"
    (*thisItem = Macintosh HD:Users:mac:checkitout copy:nothing*)
    get name of item 5 of folder "checkitout copy" of folder "mac" of folder "Users" of startup disk
        --> "nothing"
    (*thename = nothing*)
end tell

May 3, 2016 12:51 PM in response to thejrowe

The script fails because of how the Finder and AppleScript handles iterating through folders. Lists in AppleScript are dynamic.


Let's say you have three files called '1 a', '1 b', and '1 c'.


On the first iteration:


repeat with thisItem in theFolder

thisItem points to the file '1 a' because that is the first item in the list. This file gets renamed to '1_a' as expected.

On the second iteration, AppleScript re-evaluates the list and picks the second item in the list. However, the files have now been reordered - they are now '1 b', '1 c' and '1_a', since 1_a is alphabetically higher than the others. So the second iteration renames the file '1 c' to '1_c'.

On the third iteration, AppleScript re-evaluates the list again and picks the third item in the list, which is now '1_c' (the list now contains '1 b', '1_a', '1_c'). Since there are no spaces in this filename, the script exits, but it's skipped over the file '1 b', which is what you're seeing.

The solution, though, is simple. Your specific flaw is that you are iterating through the folder, so each time the loop repeats, the contents are refreshed.

Change the line:

repeat with thisItem in theFolder

to:

repeat with thisItem in (get files of theFolder)

and your problem is resolved. That is because on the first run, AppleScript builds a list of the files in the folder at that moment in time and it iterates through that list, regardless of what happens to the folder contents while the script is running.

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

applescript remove spaces replace with underscore

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.