How to copy only first 5 files in a series of subfolders

So far I’ve got this script that will copy the entire contents of a folder & its subfolders to a different location. Each of the subfolders are filled with a number of TIFF files that are named sequentially within the subfolder; 00000001.tif, 00000002.tif, 00000003.tif, etc. Each subfolder has at least 100 Tiff files in each, but I only need to copy the first 8 tiff files to the new location.

I’m not sure how to approach the logic to determine the first 8 files and copy only those over but still have the same folder structure as the original parent folder.

on run
	with timeout of 36000 seconds
		tell application "Finder"
			set sourcePath to choose folder with prompt "Please select SOURCE folder:"
			set savePath to choose folder with prompt "Please select DESTINATION folder:"
			
			duplicate sourcePath to savePath
			
		end tell
	end timeout
end run

Hi. This should be fast enough if you’re only duplicating eight files (or five!) from each subfolder:

on run
	with timeout of 36000 seconds
		set rootFolder to (choose folder with prompt "Please select SOURCE folder:")
		set destinationFolder to (choose folder with prompt "Please select DESTINATION folder:")
		
		copyTrim(rootFolder, destinationFolder)
	end timeout
end run

on copyTrim(origFolder, destinationFolder) -- Recursive handler.
	tell application "Finder"
		set origFolder to folder (origFolder as Unicode text)
		set folderName to name of origFolder
		try
			set newFolder to (make new folder at destinationFolder with properties {name:folderName})
			if ((count origFolder each file) > 0) then
				duplicate {file "00000001.tif", file "00000002.tif", file "00000003.tif", file "00000004.tif", file "00000005.tif", file "00000006.tif", file "00000007.tif", file "00000008.tif"} of origFolder to newFolder
			end if
			set subfolders to folders of origFolder
			repeat with i from 1 to (count subfolders)
				my copyTrim(a reference to item i of subfolders, newFolder)
			end repeat
		on error errMsg number errNum
			if (errNum is not -128) then
				display dialog errMsg buttons {"OK"} default button 1 with icon stop
				error number -128
			end if
		end try
	end tell
end copyTrim

Edits: Corrected an unwise edit-while-posting that sabotaged the script!
Stopped the deliberate “Cancel” error being caught by the ‘try’ blocks at higher recursion levels

Hi Nigel -

Thanks for the script, but it seems to error when it tries to copy the first TIFF file. Here’s the Event Log:

tell current application
choose folder with prompt “Please select SOURCE folder:”
alias “docsvcs:Scanning:thesis-New:test:”
choose folder with prompt “Please select DESTINATION folder:”
alias “docsvcs:Scanning:abstracts:”
end tell
tell application “Finder”
get folder “docsvcs:Scanning:thesis-New:test:”
folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
get name of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
“test”
make new folder at alias “docsvcs:Scanning:abstracts:” with properties {name:“test”}
folder “test” of folder “abstracts” of folder “Scanning” of disk “docsvcs”
count every file of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
0
get every folder of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
{folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Bird08” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Blakey06” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Bobko08” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Bomblies09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Brennen09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Briggs09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Chartrand09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Che08” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Ching04” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Choi09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, folder “Cirincione08” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”}
get folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
“docsvcs:Scanning:thesis-New:test:Abolina09:”
get folder “docsvcs:Scanning:thesis-New:test:Abolina09:”
folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
get name of folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
“Abolina09”
make new folder at folder “test” of folder “abstracts” of folder “Scanning” of disk “docsvcs” with properties {name:“Abolina09”}
folder “Abolina09” of folder “test” of folder “abstracts” of folder “Scanning” of disk “docsvcs”
count every file of folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”
63
copy {file “00000001.tif” of folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, file “00000002.tif” of folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, file “00000003.tif” of folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, file “00000004.tif” of folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”, file “00000005.tif” of folder “Abolina09” of folder “test” of folder “thesis-New” of folder “Scanning” of disk “docsvcs”} to folder “Abolina09” of folder “test” of folder “abstracts” of folder “Scanning” of disk “docsvcs”
display dialog “Finder got an error: Can’t set folder "Abolina09" of folder "test" of folder "abstracts" of folder "Scanning" of disk "docsvcs" to file "00000001.tif" of folder "Abolina09" of folder "test" of folder "thesis-New" of folder "Scanning" of disk "docsvcs".” buttons {“OK”} default button 1 with icon stop
{button returned:“OK”}
display dialog “User canceled.” buttons {“OK”} default button 1 with icon stop
{button returned:“OK”}
“User canceled.”

Hi, luvnrocs.

I haven’t been able to reproduce your error message, which only mentions not being able to set the destination folder to file “00000001.tif”. I can force a similar error by removing that file before running the script, but the error’s about not being able to set the destination folder to the whole list of files, not just the missing one.

I’ll look at it again tomorrow (BST). What version of the Finder are you using?

10.5.6

I’ve fixed the “User canceled.” dialog that appeared after the main error one. (I’d forgotten that the deliberate error would be caught by the ‘try’ at the previous recursion level.) But I still can’t work out what’s going wrong on your machine. The script runs successfully on both my machines (Tiger and Jaguar), using locations on the startup disks, locations on attached disks, locations on one machine acting as a server for the other, and locations on disks attached to the serving machine. I simply can’t reproduce your error message.

However, the Finder’s long been famous for introducing different kinds of scripting flakiness with each version, so maybe that’s the problem on your machine. I’ll see if I can come up with a shell script alternative (unless someone beats me to it).

I’m assuming, by the way, that files “00000001.tif” thru “00000008.tif” always exist in any subfolder that contains files.

OK. Here’s an AppleScript/shell-script version. It’s faster than the Finder one. Hope it fares better than it in Leopard.

on run
	with timeout of 36000 seconds
		set rootFolder to (choose folder with prompt "Please select SOURCE folder:")
		set destinationFolder to (choose folder with prompt "Please select DESTINATION folder:")
		
		copyTrim(rootFolder, destinationFolder)
	end timeout
end run

on copyTrim(origFolder, destinationFolder)
	set origPath to POSIX path of origFolder
	set destinationPath to POSIX path of destinationFolder
	
	-- Identify all the subfolders in the source hierarchy.
	set subfolderPaths to (do shell script "ls -R " & quoted form of origPath & " | grep / ")
	
	set astid to AppleScript's text item delimiters
	-- "Subtract" the source-folder path from the subfolder paths.
	set AppleScript's text item delimiters to origPath & "/"
	set subpaths to subfolderPaths's text items
	set AppleScript's text item delimiters to ""
	set subpaths to subpaths as text
	-- Replace the colon at the end of each line with a forward slash.
	set AppleScript's text item delimiters to ":"
	set subpaths to subpaths's text items
	set AppleScript's text item delimiters to "/"
	set subpaths to subpaths as text
	-- Append the source-folder name to the destination path.
	set destinationPath to destinationPath & text item -2 of origPath & "/"
	set AppleScript's text item delimiters to astid
	
	-- Recreate each source subfolder at the destination and copy over files "00000001.tif" thru "00000008.tif".
	-- Missing files will be ignored unless they're *all* missing.
	repeat with thisSubpath in (get paragraphs of subpaths)
		try
			do shell script "mkdir -p " & quoted form of (destinationPath & thisSubpath) & " ; cp -p " & quoted form of (origPath & thisSubpath) & "0000000[1-8].tif " & quoted form of (destinationPath & thisSubpath)
		on error errMsg
			display dialog errMsg with icon caution
		end try
	end repeat
end copyTrim

I figured out what the original problem was…The very first folder I had it copying did not have the files numbered correctly. They were numbered starting at 65 instead of 1. Argh! Sorry about that. I changed the naming and it works great.

As to your other question about whether there might be folders without those called files, the answer is actually yes. There may be folders scattered within the parent folder that only have a PDF file in them. I also want them to copy over completely. I was going to try and see if once I got the main script I could figure out how to add the if then part in there to deal with those folders. All of the PDF folders have the characters “-esub” as their last 5 characters suffix, but the total foldername length is variable.

I haven’t tried the shell script yet, but thanks.

Hi, luvnrocs.

Glad the Finder version works after all. :slight_smile:

Here are adaptations of both scripts to handle this too.

Finder:

on run
	with timeout of 36000 seconds
		set rootFolder to (choose folder with prompt "Please select SOURCE folder:")
		set destinationFolder to (choose folder with prompt "Please select DESTINATION folder:")
		
		copyTrim(rootFolder, destinationFolder)
	end timeout
end run

on copyTrim(origFolder, destinationFolder) -- Recursive handler.
	tell application "Finder"
		set origFolder to folder (origFolder as Unicode text)
		set folderName to name of origFolder
		try
			set newFolder to (make new folder at destinationFolder with properties {name:folderName})
			if ((count origFolder each file) > 0) then
				if (folderName ends with "-esub") then -- "-esub" folder containing PDF(s).
					duplicate every file of origFolder to newFolder
				else -- Other folder containing TIFFs.
					duplicate {file "00000001.tif", file "00000002.tif", file "00000003.tif", file "00000004.tif", file "00000005.tif", file "00000006.tif", file "00000007.tif", file "00000008.tif"} of origFolder to newFolder
				end if
			end if
			set subfolders to folders of origFolder
			repeat with i from 1 to (count subfolders)
				my copyTrim(a reference to item i of subfolders, newFolder)
			end repeat
		on error errMsg number errNum
			if (errNum is not -128) then
				display dialog errMsg buttons {"OK"} default button 1 with icon stop
				error number -128
			end if
		end try
	end tell
end copyTrim

Shell:

on run
	with timeout of 36000 seconds
		set rootFolder to (choose folder with prompt "Please select SOURCE folder:")
		set destinationFolder to (choose folder with prompt "Please select DESTINATION folder:")
		
		copyTrim(rootFolder, destinationFolder)
	end timeout
end run

on copyTrim(origFolder, destinationFolder)
	set origRoot to POSIX path of origFolder
	set destRoot to POSIX path of destinationFolder
	
	-- Identify all the subfolders in the source hierarchy.
	set subfolderPaths to (do shell script "ls -R " & quoted form of origRoot & " | grep / ")
	
	set astid to AppleScript's text item delimiters
	-- "Subtract" the source-folder path from the subfolder paths.
	set AppleScript's text item delimiters to origRoot & "/"
	set subpaths to subfolderPaths's text items
	set AppleScript's text item delimiters to ""
	set subpaths to subpaths as text
	-- Replace the colon at the end of each line with a forward slash.
	set AppleScript's text item delimiters to ":"
	set subpaths to subpaths's text items
	set AppleScript's text item delimiters to "/"
	set subpaths to subpaths as text
	-- Append the source-folder name to the destination path.
	set destRoot to destRoot & text item -2 of origRoot & "/"
	set AppleScript's text item delimiters to astid
	
	-- Recreate each source subfolder at the destination and copy over the relevant contents.
	-- Missing files will be ignored unless they're *all* missing.
	repeat with thisSubpath in (get paragraphs of subpaths)
		set destPath to quoted form of (destRoot & thisSubpath)
		try
			if (thisSubpath ends with "-esub/") then -- "-esub" folder containing PDF(s).
				do shell script "mkdir -p " & destPath & " ; cp -p " & quoted form of (origRoot & thisSubpath) & "*.pdf " & destPath
			else -- Other folder containing TIFFs.
				do shell script "mkdir -p " & destPath & " ; cp -p " & quoted form of (origRoot & thisSubpath) & "0000000[1-8].tif " & destPath
			end if
		on error errMsg
			display dialog errMsg with icon caution
		end try
	end repeat
end copyTrim

The Finder script worked beautifully!

What is the difference between a shell script and a Finder script anyways besides speed?

Thanks again.

The shell script effectually runs commands that are part of Mac OS X’s Unix underpinning. The Finder script sends individual Apple events to the application “Finder”, which probably uses Unix to carry them out anyway ” with the added overhead of interpreting the events, deciding on and making the appropriate Unix calls, updating its own records, and sending acknowledgements back to the script.

One difference between the scripts is that if any of the files “00000001.tif” thru “00000008.tif” are missing from a subfolder, the Finder script will error and stop, whereas the shell-script script will simply duplicate the ones that are there and carry on. The Finder one can be modified ” for instance, deleting the ‘error number -128’ line will allow it to carry on without duplicating the files from that particular folder ” but I think the shell-script one’s a better bet.