Detecting/Creating Matching Directory Structure on Backup Volume

I need to write a routine, but am not sure how to approach the problem.

I have an existing server (Volume 1) with a group of files and folders. I have a script that identified folders for moving to a secondary server (Volume 2) before deleting from the primary (Volume 1).

The files/folders moved to Volume 2 must be placed in exactly the same folder structure for organizational reasons, which means: a) the script must detect if the folder structure on Volume 2 already matches Volume 1 for that particular file and use file/folder in the existing folder structure if it exists, b) if the folder structure doesn’t exists, then create it before copying the flle/folder,and c) the folder structure may partially exist (so the script must be able to create the missing bits.

EXAMPLE 1:

Volume 1
–Brand
----Subbrand
------Sublevel 1
--------Job Folder

Volume 2
(nothing exists)

Script shoulder create…

–Brand
----Subbrand
------Sublevel 1

…and deposit Job Folder into Sublevel 1

EXAMPLE 2:

Volume 2
–Brand

Script should create…
----Subbrand
------Sublevel 1

…and deposit Job Folder into Sublevel 1

I think you get the idea.

I assume this will be some sort of recursion to test each level of the path to see if it exists and matches, and create anything missing until it gets the proper structure created.

But maybe there is an AppleScript or command-line way of approaching this that is easier?

Wouldn’t mind a little (or alot) of help, as I’ve been away from AppleScript programming for a while. The existing detection scripts are all in AppleScript, so this new code needs to integrate into that. Not looking to dive into Xcode for this…just boring old Script Debugger. :slight_smile:

Hi,

the shell command ditto is able to copy items and create intermediate directories at the same time

Thanks, this command sounds like just the trick…if I can get it to work.

So I’ve been fiddling around with ditto but so far, when I tell it to copy a folder from one place to another, it copies the contents of the target folder to the new location, without the enclosing folder or the directory structure leading to the enclosing folder.

A bit like emptying multiple folders into one massive folder. Not exactly the effect I had in mind:

ditto Volume 1:Folder 1 Volume 2:Folder 1

Volume 1
–Folder 1
----Subfolder 1
------File 1
------File 2
----Subfolder 2
------File 3
------File 4

Volume 2
–Folder 1
----File 1
----File 2
----File 3
----File 4

Any idea what I’m doing wrong?

something like this, it assumes that both source and destination locations are not on the boot volume

set sourcePath to "/Volumes/Volume 1/Subfolder 1/File 1"
set destinationVolume to "Volume 2"
set {TID, text item delimiters} to {text item delimiters, "/"}
set relativePath to (text items 4 thru -1 of sourcePath) as text -- "Subfolder 1/File 1"
set text item delimiters to TID
set destinationPath to "/Volumes/" & destinationVolume & "/" & relativePath -- "/Volumes/Volume 2/Subfolder 1/File 1"
do shell script "ditto " & quoted form of sourcePath & space & quoted form of destinationPath

Ah, I figured out the problem, but not sure how to solve it.

Here’s an example of a ditto command generated by my script (which is wrong):

ditto '/Volumes/Server/Completed Projects/Brand/Project Folder' '/Volumes/Archive/Location'

I guess what I need is for the script to properly input a dynamic subfolder. So if the script input assigned to move_to is /Volumes/Archive/Location then the ditto destination would be /Volumes/Archive/Location/Completed Projects/Brand/Project Folder (using the example above).

Somehow I need to graft the top-level ditto destination to a specific portion of the source location so the structure gets built properly.

Is there an easy way to tease the two pieces together?

set sourcePath to "/Volumes/Server/Completed Projects/Brand/Project Folder"
set destinationVolumePrefix to "Archive/Location"
set {TID, text item delimiters} to {text item delimiters, "/"}
set relativePath to (text items 4 thru -1 of sourcePath) as text -- "Completed Projects/Brand/Project Folder"
set text item delimiters to TID
set destinationPath to "/Volumes/" & destinationVolumePrefix & "/" & relativePath -- "/Volumes/Archive/Location/Completed Projects/Brand/Project Folder"
do shell script "ditto " & quoted form of sourcePath & space & quoted form of destinationPath

Been a few years since I’ve messed with my scripts, and here is StefanK coming to my rescue as usual.

Worked like a charm, thanks!

You’re welcome

It’s been a while since I got back to this, and my manager is ready for me to turn-on the move-n-delete aspects of my script, but it just occurred to me:

If ditto encounters a problem moving a file (because of permissions, corrupt file, whatever), will that error be “seen” by AppleScript so that using try will work properly? So would this work?

try
	do shell script "ditto " & [i][supplied path names][/i]
on error errMsg
	[i][do some logging and make sure the files are not deleted from the source volume][/i]
end try

???