I have Folder A that contains Folder 1, Folder 2, and Folder 3 (obviously the names will be different so the script should refer to them generically)
I want move each of these folders to Folder B, but only if none of them exist in Folder B. At the first indication that even one of them exists in Folder B, I want to throw up a dialog “Operation terminated.” and terminate the directory comparison as well as the rest of the script so that nothing is copied. If, in fact, none of the three folders exists, they should each be copied to Folder B
I have tried the standard loop (“repeat with…”) that can identify whether one or more of the three folders in Folder A are also in Folder B, but by the time it loops through them all, the script is way down the road copying the ones that do not exist, which is not what I want.
In this particular case it’s all or nothing, so I want to essentially take an accounting of the source Folder A first without doing anything until it knows that Folder 1, Folder 2, or Folder 3 are unique in Folder B.
It is unclear, you want move or you want duplicate the folders. Assuming you want duplicate the folders, the script is (replace duplicate command with move command, if you need):
set Folders123_names to {"exif-samples-master", "icns", "untitled"}
set Folder_A_name to "HARD_DISK:Users:123:Downloads:Test files"
set Folder_B_name to "HARD_DISK:Users:123:Downloads"
tell application "Finder" to set Folder_B_folderNames to name of folders of folder Folder_B_name
set containsOneOfThem to false
repeat with nextName in Folders123_names
if nextName is in Folder_B_folderNames then
set containsOneOfThem to true
exit repeat
end if
end repeat
if containsOneOfThem is true then
display dialog "Operation terminated"
else
repeat with nextName in Folders123_names
tell application "Finder" to duplicate folder (Folder_A_name & ":" & nextName) to folder Folder_B_name
end repeat
end if
The OP’s request is easily done with basic AppleScript. My suggestion uses ASObjC and would be of value if Folder B contains an extremely large number of files and folders. My script does not include the actual copy/move code but that is easily added depending on how the OP wants to handle this.
use framework "Foundation"
use scripting additions
set folderA to (choose folder)
set setA to getFolders(folderA)
set folderB to (choose folder)
set setB to getFolders(folderB)
set setsIntersect to ((setA's intersectsSet:setB) as integer = 1)
if setsIntersect then display dialog "Operation terminated" buttons {"OK"} cancel button 1 default button 1
-- put copy/move code here
on getFolders(theFolder)
set fileManager to current application's NSFileManager's defaultManager()
set directoryKey to current application's NSURLIsDirectoryKey
set packageKey to current application's NSURLIsPackageKey
set hiddenFileOption to current application's NSDirectoryEnumerationSkipsHiddenFiles as integer
set packageOption to current application's NSDirectoryEnumerationSkipsPackageDescendants
set folderContents to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{directoryKey, packageKey} options:(hiddenFileOption + packageOption) |error|:(missing value)
set theFolders to {}
repeat with anItem in folderContents
set {theResult, theValue} to (anItem's getResourceValue:(reference) forKey:directoryKey |error|:(missing value))
if theValue as boolean then
set {theResult, theValue} to (anItem's getResourceValue:(reference) forKey:packageKey |error|:(missing value))
if not theValue as boolean then
set end of theFolders to anItem's lastPathComponent() as text
end if
end if
end repeat
return (current application's NSSet's setWithArray:theFolders)
end getFolders
Using your help, here is my final script that actually works. I was wondering, though, if it’s a little too wordy and could be tightened up somewhat because as you can see, I have to do a fair amount of parsing in both repeat loops which seems redundant.
tell application "Finder"
set theFiles to folder "Hard Drive:Users:Macintosh:Downloads" as alias
set theLocation to folder "Hard Drive:Users:Macintosh:Documents:Videos" as alias
set theFolder to "Hard Drive:Users:Macintosh:Documents:Videos:Security Videos"
set theTarget to "Macintosh Backup:Security Videos" as alias
set containsOneOfThem to false
repeat with archiveFolder in (theLocation's folders as list)
set originName to name of archiveFolder as text
set yearName to theTarget & "Security Videos " & text 17 thru 20 of originName as text
set monthName to yearName & ":Security Videos " & text 17 thru 23 of originName as text
set actualName to monthName & ":" & originName as text
if exists (folder actualName) then
set containsOneOfThem to true
exit repeat
end if
end repeat
if containsOneOfThem is true then
display dialog "Operation terminated"
else
repeat with archiveFolder in (theLocation's folders as list)
set originName to name of archiveFolder as text
set yearName to theTarget & "Security Videos " & text 17 thru 20 of originName as text
set monthName to yearName & ":Security Videos " & text 17 thru 23 of originName as text
set actualName to monthName & ":" & originName as text
if not (exists folder monthName) then
make new folder at yearName with properties {name:text 1 thru 23 of originName}
move archiveFolder to monthName
else
move archiveFolder to monthName
end if
end repeat
end if
end tell
By the way, I actually want to move the folders to another HD and wondered whether the move command would actually do that (i.e. copy and then delete) or whether for all practical purposes when using another HD there is no difference between move and copy, meaning that I would need the script to delete the original folders after moving in any event.
moving to other HD copies, so you should delete the source folder yourself. This should work:
set Folder_A_path to "HARD_DISK:Users:123:Downloads:untitled:" -- my HD's folder path
set Folder_B_path to "Untitled:" -- my USB disk's root folder's path
tell application "Finder" to set Folder_A_folderNames to name of folders of folder Folder_A_path
tell application "Finder" to set Folder_B_folderNames to name of folders of folder Folder_B_path
set containsOneOfThem to false
repeat with nextName in Folder_A_folderNames
if nextName is in Folder_B_folderNames then
set containsOneOfThem to true
exit repeat
end if
end repeat
if containsOneOfThem is true then
display dialog "Operation terminated"
else
tell application "Finder" to set destinationFolder to folder Folder_B_path
repeat with nextName in Folder_A_folderNames
tell application "Finder"
set nextFolder to folder (Folder_A_path & nextName)
tell application "Finder" to duplicate nextFolder to destinationFolder
delete nextFolder
end tell
end repeat
end if
Figured as much on the copy/move to another HD. Any way to avoid restating the file name parsing variables in both repeat blocks? (See Message #4 above).
In case it’s not evident, the script takes a folder named: Security Videos 02-15-21 and copies it over to: Hard Drive: Security Videos" Security Videos 2021: Security Videos 2021-02.
And because every month a new folder needs to be created, it checks to see if that next month’s folder exists (i.e. 2021-03) and if not, it creates one when necessary before copying that folder over.
Thus the need to parse out the various paths along the way from the original folder name.
I don’t quite understand your script in post #4. It contains a lot of confusion with references and paths. And, I still can’t fully understand your purpose, but I tried to figure it out by touch. For understandable reasons, I can’t test this for you:
set theLocation to ((path to documents folder) as text) & "Videos"
set theFolder to theLocation & ":Security Videos"
set theTarget to "Macintosh Backup:Security Videos"
set {originNames, yearNames, monthNames} to {{}, {}, {}}
tell application "Finder"
set locationFolders to (folder theLocation)'s folders
repeat with archiveFolder in locationFolders
set originName to name of archiveFolder
set end of originNames to originName
set yearName to theTarget & "Security Videos " & text 17 thru 20 of originName
set end of yearNames to yearName
set monthName to yearName & "Security Videos " & text 17 thru 23 of originName
set end of monthNames to monthName
if exists (folder (monthName & ":" & originName)) then
display dialog "Operation terminated"
return
end if
end repeat
repeat with i from 1 to count locationFolders
set monthName to item i of monthNames
if not (exists folder monthName) then make new folder at folder (item i of yearNames) with properties {name:text 1 thru 23 of (item i of originNames)}
duplicate (item i of locationFolders) to folder monthName
-- delete archiveFolder -- recomment to delete
end repeat
end tell
Yeah, I figured it was confusing so sorry about that.
On the computer I have a folder (Hard Drive:Users:Macintosh:Documents:Security Videos) that contains numerous dated subfolders, named as follows: “Security Videos 02-15-21” etc.
So, inside Security Videos folder are numerous such dated folders: “Security Videos 02-13-21”. “Security Videos 02-14-21”,“Security Videos 02-15-21”, etc.
I need the script to backup these dated folders to their monthly counterpart folders on this HD (Macintosh Backup:Security Videos:Security Videos 2021:Security Videos 2021-02) based on the year and month in their name.
The script thus needs to perform the following:
Check to make sure none of the dated folders already exist inside their respective monthly folders on the backup drive, and if so terminate the script.
If all the dated folders are unique, then…
Check to make sure the yearly folder (i.e. Security Videos 2021) exists inside the main folder (Macintosh Backup:Security Videos), and if not create one.
Check to make sure the monthly folder (i.e. Security Videos 2021-02) exists inside the year folder, and if not create one.
Backup the dated folders into their corresponding monthly folders on the backup Hard Drive.
I edited some things. Test this and tell as if it works as expected:
set theLocation to ((path to documents folder) as text) & "Videos"
set theFolder to theLocation & ":Security Videos"
set theTarget to "Macintosh Backup:Security Videos"
set {originNames, yearNames, monthNames} to {{}, {}, {}}
tell application "Finder"
set locationFolders to (folder theLocation)'s folders
repeat with archiveFolder in locationFolders
set originName to name of archiveFolder
set end of originNames to originName
set |year| to "20" & (text 23 thru 24 of originName)
set yearName to theTarget & ":Security Videos " & |year|
set end of yearNames to yearName
set monthName to yearName & ":Security Videos " & |year| & "-" & text 17 thru 18 of originName
set end of monthNames to monthName
if (exists folder yearName) then
if exists (folder (monthName & ":" & originName)) then
display dialog "Operation terminated"
return
end if
else
make new folder at folder theTarget with properties {name:"Security Videos " & |year|}
end if
end repeat
repeat with i from 1 to count locationFolders
set monthName to item i of monthNames
if not (exists folder monthName) then make new folder at folder (item i of yearNames) with properties {name:text 1 thru 23 of (item i of originNames)}
duplicate (item i of locationFolders) to folder monthName
-- delete archiveFolder -- recomment to delete
end repeat
end tell
I think, your originNames is not “Security Videos 02-13-21” as you indicated, but contains some additional spaces.
Something like this? “Security Videos 02 - 13-21”
Copy and paste here one name from your Finder, and past here, in the AppleScript tags, please.
Look:
set theTarget to "Macintosh Backup:Security Videos"
set originName to "Security Videos 02 - 13-21" -- THIS
set |year| to "20" & (text 23 thru 24 of originName)
set yearName to theTarget & ":Security Videos " & |year|
set monthName to yearName & ":Security Videos " & |year| & "-" & text 17 thru 18 of originName
-- Result:
-- Macintosh Backup:Security Videos:Security Videos 203-:Security Videos 203--02
And, see now:
set theTarget to "Macintosh Backup:Security Videos"
set originName to "Security Videos 02-13-21" -- THIS
set |year| to "20" & (text 23 thru 24 of originName)
set yearName to theTarget & ":Security Videos " & |year|
set monthName to yearName & ":Security Videos " & |year| & "-" & text 17 thru 18 of originName
--> "Macintosh Backup:Security Videos:Security Videos 2021:Security Videos 2021-02"