Script Move files into folders separated by first 3 characters

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.

Hi,

give this a try:

Kind regards, Eric

Hi Eric.

The last line above should preferably be:

set firstThree to text 1 thru 3 of theText

‘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

OMG! THANK YOU ALL!!! NIGEL and EricLipton Worked like a charm!!! You all saved my booty

How would I add a “chose Folder”?