I have the following script (which almost works) that’s intended to ask for a source folder (known to contain folders “Scripts” and “Plugins”) and then ask for a second folder to copy Scripts and Plugins into. The second folder will already have folders with those names, and the plugins folder in the target will already have a few files in it. I was hoping that “without replacing” would allow the duplication, ignoring files that already exist, which is what I want. Unfortunately, when I specify “without replacing” the script errors and does nothing. “With replacing” just overwrites the destination folders, which is what I would expect. What I would really like here is a merge with the target. Can someone point me in the right direction? Here’s my script, which works fine if accept a total overwriting of the destination folders.
-- Function to choose a folder with a dialog
on chooseFolderWithDialog(promptMessage)
set selectedFolder to choose folder with prompt promptMessage
return selectedFolder
end chooseFolderWithDialog
-- Function to copy folders
on copyFolders(source, destination)
tell application "Finder"
try
set sourceFolder to (source as text) & "Plugins"
set destinationFolder to (destination as text) & "Plugins"
duplicate folder sourceFolder to destination without replacing
set sourceFolder to (source as text) & "Scripts"
set destinationFolder to (destination as text) & "Scripts"
duplicate folder sourceFolder to destination without replacing
on error errMsg
display dialog "Error copying " & (source as text) & " TO " & (destination as text) & ": " & errMsg
end try
end tell
end copyFolders
-- Main script
try
set sourceFolder to chooseFolderWithDialog("Please select the SOURCE folder containing the subfolders.")
set destinationFolder to chooseFolderWithDialog("Please select the DESTINATION folder containing the subfolders.")
copyFolders(sourceFolder, destinationFolder)
end try
Is it necessary that you copy the folders rather than the contents of those folders? I think that this will be an issue for you as copying the folder will simply replace any existing one. I don’t think that applescript can use the Finder’s merge functionality.
One suggestion… remove the main script try statement. It prevents you from being told what went wrong. If useful, you can add it back once the script is performing as desired.
Here is an alternative approach that uses the shell’s cp utility to copy the contents of the specified folders to their destination†. It will create a log file in the parent of the destination folder that contains a list of the copied files.
use scripting additions
set sourceFolder to chooseFolderWithDialog("Please select the SOURCE folder containing the subfolders.")
set destinationFolder to chooseFolderWithDialog("Please select the DESTINATION folder containing the subfolders.")
set text item delimiters to ":"
set destParent to (text items 1 thru -3 of (destinationFolder as text) as text) & ":"
set text item delimiters to ""
-- prepare quoted logfile path
set destParent to POSIX path of destParent
set dateStamp to longstamp()
set deskLog to quoted form of (destParent & "/log" & dateStamp & ".txt")
-- quote paths to folders
set qSource to quoted form of POSIX path of sourceFolder
set qDestination to quoted form of POSIX path of destinationFolder
-- generate shell cp command
set cmd to "cp -Rnv " & qSource & space & qDestination
--> "cp -Rn '/Users/kkeller/Desktop/archive/sorc/' '/Users/kkeller/Desktop/archive/desto/'"
try
do shell script cmd
on error errMsg
-- display dialog "Error copying " & (source as text) & " TO " & (destination as text) & ": " & errMsg
do shell script "printf \"" & errMsg & "\" >" & deskLog -- save `cp` feedback to log
end try
-- handler to get date/time string
on longstamp()
set cd to (current date)
set sds to short date string of cd
set ts to time string of cd
set tstamp to sds & space & ts
set text item delimiters to {"-", ":", space}
set tst to text items of tstamp as text -- replace space with dash
end longstamp -- "2025-02-25-12-41-AM"
-- handler to choose a folder with a dialog
on chooseFolderWithDialog(promptMessage)
set selectedFolder to choose folder with prompt promptMessage
return selectedFolder
end chooseFolderWithDialog
Notes
The option -R will cause cp to copy subfolders and their contents
The option -n will keep cp from overwriting already existing files
† The script handles this automatically but for reference, the specified path to the source directorymust end with a ‘/’, or it will copy the folder rather than the contents of the folder. It is not necessary for the destination directory. For example:
cp -Rn sourceDir/ destDir/
But not
cp -Rn sourceDir destDir/
You can read the documentation for the cp command in the Terminal with man cp.
GaryT. I tested Mockman’s suggestion and it works great. The following is a Finder suggestion that does what you want.
-- Function to choose a folder with a dialog
on chooseFolderWithDialog(promptMessage)
set selectedFolder to choose folder with prompt promptMessage
return selectedFolder
end chooseFolderWithDialog
-- Function to copy folders
on copyFolders(source, destination)
tell application "Finder"
set sourceFolder to (source as text) & "Plugins:"
set sourceFolderFiles to every file in folder sourceFolder
set targetFolder to (destination as text) & "Plugins:"
if exists folder targetFolder then
repeat with aFile in sourceFolderFiles
try
duplicate aFile to folder targetFolder without replacing
end try
end repeat
end if
set sourceFolder to (source as text) & "Scripts:"
set sourceFolderFiles to every file in folder sourceFolder
set targetFolder to (destination as text) & "Scripts:"
if exists folder targetFolder then
repeat with aFile in sourceFolderFiles
try
duplicate aFile to folder targetFolder without replacing
end try
end repeat
end if
end tell
end copyFolders
-- Main script
try
set sourceFolder to chooseFolderWithDialog("Please select the SOURCE folder containing the subfolders.")
set destinationFolder to chooseFolderWithDialog("Please select the DESTINATION folder containing the subfolders.")
copyFolders(sourceFolder, destinationFolder)
end try
I tested your script, but no copying took place. I started with a folder from my Documents folder, and an empty, newly created folder on the desktop. Selected each at the prompts, and no files were copied. Any ideas?
Hey, thank you all for the very helpful advice and comments. My scripting talent is obviously a bit lacking. Using a combination of the techniques you guys provided, I was not only able to get this working, but added a few refinements to it as well. While I kinda understand the OOP nature of Applescript, I sometimes lose focus as to the object I’m actually working with. I’m in the process of leveraging Alfred workflows on my machine, so I’ll probably be back here a lot going forward. Not that Alfred doesn’t do a lot out of the box, but it seems everything I want to do is just a little different then what’s built it.