Hello
I was hoping someone could help me with this. I have hundreds of files in a folder and I would like them separated into folders by their first three characters. The characters could be numbers or letters. i.e. 1a123ok8e4kd, 1a123ok8e55454, 1a123ok77676444, 152lo2355, etc. And if there are duplicate first 3 characters, they should go into a folder that is already created. Is this possible?
Thanks for your time.
‘characters 1 thru 3 of theText as string’ creates a list of the three characters and then coerces it to text. When lists are coerced to text, the current value of AppleScript’s text item delimiters is inserted between the items, so the delimiters should explicitly be set to “” before the coercion’s done here. On the other hand, ‘text 1 thru 3 of theText’ simply extracts the substring directly, which is more efficient and saves having to worry about delimiters.
You’re explicitly coercing workFolder to string every time, so your code’s ostensibly testing for the existence of the string, coercing it to string again if it does exist, and moving files to it instead of to the folder. I haven’t tried lately to see if it actually works or not in the Finder, but it’s best to leave out the 'as string’s and to keep the folder references.
Since the OP claims to have hundreds of files in the folder, it would be better to set a variable to it at the beginning of the script than to work it out again every time from the front window:
tell application "Finder"
set mainFolder to (folder of window 1) as alias
set listFiles to files of mainFolder
repeat with i in listFiles
set theText to name of i
set firstThree to text 1 thru 3 of theText
if (exists folder firstThree of mainFolder) then
set the workFolder to folder firstThree of mainFolder
else
set workFolder to (make new folder at mainFolder with properties {name:firstThree})
end if
move (i) to workFolder
end repeat
end tell
There are faster ways to do this than using the Finder, but I’m just trying to help with your code here.
When posting AppleScript code on MacScripter, would you mind wrapping it in our special [applescript][/applescript] tags instead of using [quote][/quote]? The [applescript] tags produce a box with a clickable link, as above.
Further to my post above, one way Eric’s script might be speeded up, even using the Finder, might be to sort the file names lexically first and to work through those. Then the existence of a destination folder would only have to be tested when a new ‘firstThree’ came up, not with every file:
tell application "Finder"
set mainFolder to (folder of window 1) as alias
set fileNames to name of files of mainFolder
end tell
sort(fileNames, 1, -1)
set i to 1
set nameCount to (count fileNames)
repeat until (i > nameCount)
set firstThree to text 1 thru 3 of item i of fileNames
tell application "Finder"
if (exists folder firstThree of mainFolder) then
set the workFolder to folder firstThree of mainFolder
else
set workFolder to (make new folder at mainFolder with properties {name:firstThree})
end if
repeat while ((i ≤ nameCount) and (item i of fileNames begins with firstThree))
move file (item i of fileNames) of mainFolder to workFolder
set i to i + 1
end repeat
end tell
end repeat
(* Insertion sort
Algorithm: unknown author.
AppleScript implementation: Arthur J. Knapp and Nigel Garvey, 2003.
Parameters: (list, range index 1, range index 2)
*)
on sort(theList, l, r)
script o
property lst : theList
end script
set listLen to (count theList)
if (listLen > 1) then
if (l < 0) then set l to listLen + l + 1
if (r < 0) then set r to listLen + r + 1
if (l > r) then set {l, r} to {r, l}
set u to item l of o's lst
repeat with j from (l + 1) to r
set v to item j of o's lst
if (v < u) then
set here to l
set item j of o's lst to u
repeat with i from (j - 2) to l by -1
tell item i of o's lst
if (it > v) then
set item (i + 1) of o's lst to it
else
set here to i + 1
exit repeat
end if
end tell
end repeat
set item here of o's lst to v
else
set u to v
end if
end repeat
end if
return -- nothing.
end sort