Repeat actions on a list that changes

Dear Friends,
How do I write the syntax to do this? I have commented the parts I have done sucessfuly.

  1. Choose a folder – I can do this
  2. List its contents – I can do this
  3. Choose the first item in the folder from the list; display a dialog with its name; shorten the name to its basic component (e.g. dog_scans_01.jpg → dog_scans); have the script make a folder for all the “dog_scans” and move them into the new folder – I can do this
  4. Repeat subroutines 2 and 3 until the folder is empty

It’s number four that stumps me. I can’t use a “repeat with X in List” because the list is outmoded after the first iteration of number three, and this method fails when it can’t find “dog_scan_02.jpg.” I tried writing a routine that would remove the names of the moved files from the List so that a “repeat with X in List” might work, but that was just too complex for me!

I want to stick a line like “repeat until chosen folder is empty” between 1 and 2, but I can’t figure out the syntax. (It seems like it should be easy, but I keep getting error messages when I try to compile the script. These may be due to my not knowing where to put the “end repeat” or how to construct the repeat syntax.) Is this possible? Thanks for any suggestions.

Try this:

choose folder
set sourceFolder to result

set folderList to {}

set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "_"

repeat with thisItem in (list folder sourceFolder without invisibles)
	set folderList's end to (text items 1 through -2 of thisItem) as text
end repeat

set AppleScript's text item delimiters to ASCII character 10
do shell script "uniq <<< " & quoted form of (folderList as text) without altering line endings
set folderList to text items 1 through -2 of result

set AppleScript's text item delimiters to ASTID

tell application "Finder"
	activate
	
	try
		repeat with thisItem in folderList
			make new folder at folder sourceFolder with properties {name:thisItem}
			
			move (every file of folder sourceFolder whose name starts with thisItem) to result
		end repeat
		
		display dialog "Script finished." buttons "OK" default button 1
	on error errorMsg number errorNum
		display dialog "Error (" & errorNum & "):" & return & return & errorMsg buttons "Cancel" default button 1 with icon caution
	end try
end tell

I just thought of one problem with this script. If, as an [example], you had a set of pictures named “dog_##” and another called “dog_park_##”, both sets of pictures would be moved to the “dog” folder. Any input on this issue is welcome.

A somewhat simpler approach (without the ‘moving files’ part):


--select a folder, get it's content listing
set theFolder to (choose folder)
set folderListing to (list folder theFolder)

--returns the path to the folder, we'll need it later on
set theFolderPath to (theFolder as text)

--the important part: We're using the list we created
--earlier on, and this list *doesn't* change any more
repeat with theItem in folderListing
	set thePath to (theFolderPath & (theItem as text)) as text
	set myFile to (thePath as alias)
	--at this point myFile is an AppleScript alias to the current file and you can handle it
end repeat

Model: iBook g3/800 14,1"
Browser: Safari 312
Operating System: Mac OS X (10.3.9)

Thanks for the ideas. You folks are great!

DanB: I see what you’ve done, but is it relevant? (I’m thinking this through as I type, so excuse my not understanding if I’ve gone wrong.) The idea is that I kind of WANT the list to change. If I begin with:

dog_park_01
dog_park_02
dog_home_01
dog_home_02
cat_chair_01
cat_chair_02
cat_chair_03

I want to be (Step 1) presented with a dialog that lets me truncate “dog_park_01” to “dog_park” and have all the “dog_park” files moved to a folder “dog_park.” Then, I want to be (Step 2) presented with a dialog that lets me truncate “dog_home_01” to “dog_home” and have all the “dog_home” files moved to a folder “dog_home.” After Step 1, I don’t care where the OTHER “dog_park” files are, and I don’t want to be presented with a dialog that lets me truncate “dog_park_02.” See? I really don’t want to step through the whole ORIGINAL list. It becomes irrelevant after the first “move.” Am I making sense?


Guardian: Whoa Nelly, you’re way beyond my poor understanding! I have, sadly, only a vague idea what your shell script is supposed to do. BUT, I suspect that it is editing the original list into a list of somehow “unique” items? Based on the first repeat’s truncating of the file names to remove the numbers? Interesting approach. Maybe I could then insert my own truncating dialog with its associated moving where you have an automated process?

I’ve found that the file names are so differen it’s really not possible to automate truncating them. So all I’m really trying to do is avoid having to make a new Finder selection and rerun a script for each “base name” that occurs in a folder.

Well, actually this turns out to be easy.

In English:

tell Finder
set SelectedFolder to container of selection
repeat until count of SelectedFolder = 0
set TheSelectedFile to first file of SelectedFolder
– do my stuff
end repeat
end tell

I don’t even have to select the first file in the folder. I can make new folders in the folder, too. And Bob’s your uncle. Of course I have to run this from the Scripts menu after making a Finder selection.

Thanks for your help!