Terminate script if any folders exist in another directory.

Hello all, I could use a little help, please.

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.

Thanks for any help on this!

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

KniazidisR - thanks for that!

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:

  1. 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…

  1. 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.

  2. Check to make sure the monthly folder (i.e. Security Videos 2021-02) exists inside the year folder, and if not create one.

  3. Backup the dated folders into their corresponding monthly folders on the backup Hard Drive.

  4. Delete the original dated folders when completed.

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

Getting this error:

Finder got an error: Can’t set folder “Macintosh Backup:Security Videos:Security Videos 201-:Security Videos 201–20” to folder “Macintosh Backup:Security Videos:Security Videos 201-:Security Videos 201–20”.

and these empty folders are created:

Security Videos 201-
Security Videos 202-
Security Videos 204-

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"