Copying and renaming files using Applescript and Shell

Hello,

I am attempting to automatize some file backup. My work folder (source folder) contains different subfolders. Each one of these has five different subfolders with image files in them. I only need to backup image files from specific subfolders. I am attempting to use a shell script to copy the files in these subfolders to the main folder. But I also want to rename them with the name of the parent folder. The new name should have a prefix with the parent folder’s name (theNumber).

[AppleScript]

tell application “Finder”

set sourcefolder to (choose folder) as alias

set subfolders to every folder of sourcefolder

repeat with eachfolder in subfolders
	
	set theNumber to name of eachfolder
	set facefolder to eachfolder as alias
	
	set subEnd to folder "subfolder1" of facefolder as alias
	set subSide to folder "subfolder2" of facefolder as alias
	
	do shell script "cd " & POSIX path of subEnd & "; for i in 'ls *.tiff'; do cp $i 'echo $i | sed \"s/$I/" & theNumber & "$i/g\"'; done;"
	
	do shell script "cd " & POSIX path of subSide & "; cp *.tiff " & POSIX path of sourcefolder
	
end repeat

end tell

[/AppleScript]

Thanks for any advice.

Hi. Find is a more appropriate choice than ls for this task. For future reference, you really shouldn’t place shell calls within other application’s tell blocks, as mayhem might ensue. You noted you want to exclude specific folders, but no hint was given as to which, so no effort at restriction is included in my example code. Please note that this won’t/can’t work on any file whose folder (or itself) contains a space.

do shell script "find  " & my (choose folder with prompt "Locate the SOURCE folder:")'s POSIX path & " -name '*.*' -prune -name '*.tiff' -exec sh -c ' filePath=$0 ; fileName=$(basename $filePath) ; dirName=$(dirname $filePath) ;  newPath=" & my (choose folder with prompt "Pick a DESTINATION folder:")'s POSIX path & "$(basename $dirName)\"_\"$fileName; cp {} $newPath ' {} \\;"
  • Some portion ^ was adapted from concepts learned in the thread below, which was answered by poster DJ Bazzie Wazzie, who hasn’t been seen on this forum for some time. Should you need to remove spaces or other characters from the filenames, you might also learn from it.

https://macscripter.net/viewtopic.php?id=44242

Many thanks! I will try that and also thanks for the advice. I only occasionally try to program and it is always a very steep learning curve.

Best

The solution worked great. I only have one issue. Unfortunately the external volume I want to use it on has a name with spaces in it. I tested this also on the drive and I don’t get it do work when any of the parent folders have spaces in it. I tried to escape it by framing the variable newpath with quotation marks, but so far I have no luck. It seems that quotation marks only frame the directories, not the filename.

tell application "Finder"
	
	set sourcefolder to (choose folder) as alias
	
	set subfolders to every folder of sourcefolder
	
	repeat with eachfolder in subfolders
		
		set musNo to name of eachfolder
		set facefolder to eachfolder as alias
		
		do shell script "find \"" & POSIX path of sourcefolder & musNo & "/endImages\" -name '*.tif' -exec sh -c ' filePath=$0 ; fileName=$(basename $filePath) ; dirName=$(dirname $filePath) ; newPath='" & POSIX path of sourcefolder & "'" & musNo & "_$(basename $dirName)\"_\"$fileName; cp {} $newPath ' {} \\;"
		
		
		
		
	end repeat
	
	
end tell


The sample code is already a loop, so I’m not sure why you made another loop and moved it inside the Finder’s scope. As previously advised, placing shell calls within another app’s tell block is really inadvisable; it can lead to errors, reduced performance, and/or inexplicable failure. On further examination, the spaces can be preserved with literal quotes at each $ item; I had misinterpreted them as optional, as the code still mostly works without them.

do shell script "find " & my (choose folder with prompt "Locate the SOURCE folder:")'s POSIX path & " -name '*.*' -prune -name '*.png' -exec sh -c ' filePath=\"$0\" ; fileName=$(basename \"$filePath\") ; dirName=$(dirname \"$filePath\") ; newPath=" & my (choose folder with prompt "Locate the DESTINATION folder:")'s POSIX path & "\"$(basename $dirName)_$fileName\"; cp \"$filePath\" \"$newPath\" ' {} \\;"

Many thanks! That works great.

tell application "Finder"
	
	set sourcefolder to (choose folder with prompt "Please select the folder to be processed:") as alias
	
	set destinationfolder to (choose folder with prompt "Please select the destination folder:") as alias
	
	set subfolders to every folder of sourcefolder
	
	repeat with eachfolder in subfolders
		
		set musNo to name of eachfolder
		set facefolder to eachfolder as alias
		
		if (exists folder "endImages" of facefolder) is true then
			do shell script "find \"" & POSIX path of sourcefolder & musNo & "/endImages\" -name '*.tif' -exec sh -c ' filePath=\"$0\" ; fileName=$(basename \"$filePath\") ; dirName=$(dirname \"$filePath\") ; newPath=\"" & POSIX path of destinationfolder & musNo & "_$dirName_$fileName\"; cp \"$filePath\" \"$newPath\" ' {} \\;"
		end if
		
		if (exists folder "sideImages" of facefolder) is true then
			
			do shell script "find \"" & POSIX path of sourcefolder & musNo & "/sideImages\" -name '*.tif' -exec sh -c ' filePath=\"$0\" ; fileName=$(basename \"$filePath\") ; dirName=$(dirname \"$filePath\") ; newPath=\"" & POSIX path of destinationfolder & musNo & "_$dirName_$fileName\"; cp \"$filePath\" \"$newPath\" ' {} \\;"
		end if
		
		if (exists folder "unwrapping" of facefolder) is true then
			do shell script "find \"" & POSIX path of sourcefolder & musNo & "/unwrapping\" -name '*.tif' -exec sh -c ' filePath=\"$0\" ; fileName=$(basename \"$filePath\") ; dirName=$(dirname \"$filePath\") ; newPath=\"" & POSIX path of destinationfolder & musNo & "_$dirName_$fileName\"; cp \"$filePath\" \"$newPath\" ' {} \\;"
		end if
		
	end repeat
	
	
end tell