Hello -
I’m pretty adept at piecing together bits of code, but still quite a newbie to Applescript. My challenge is that I am trying to take a DVD with many layers of folders and sub-folders, duplicate its structure to a new desitnation and copy one file from each sub-folder that contains files. So, far I have found the following bit of code that will get the most recent file (which is fine, I don’t much care which file it is):
set theFolder to choose folder
tell application "Finder"
select item -1 of (sort (get files of folder theFolder) by modification date)
end tell
Also, I’ve found a longer script that will copy files of particular file types and move them to a new, duplicate folder structure. I’ll paste it at the end of the post (sorry for not linking, but I can’t find it again and thanks to whomever wrote it). As you can see, I tried to integrate the “most recent file” bit into this longer script, but its erroring out. I would really appreciate any help or guidance anyone could give me in this.
Thanks
Here’s the script:
-- duplicate at destination the source folder's tree structure, omitting 'empty' leaf node folders, and copy all Finale files.
-- Finale Mac files have file type FIN3. Finale PC created files have name extension MUS.
property gFileTypes : {"mus"}
tell application "Finder"
-- (*begin Copy Folder Tree*)
set tSourceFolder to choose folder with prompt "Choose a folder structure to duplicate and copy Finale files"
if tSourceFolder is false then return "User Cancelled"
set tDestFolder to choose folder
my copyItems(tSourceFolder, tDestFolder)
log {"Finished"}
end tell
on copyItems(pSourceFolder, pDestFolder)
tell application "Finder"
close windows
set tSourceFolderName to name of pSourceFolder as string
make new folder at pDestFolder with properties {name:tSourceFolderName}
set tNewDestFolder to (folder tSourceFolderName of folder pDestFolder) as alias
-- copy or move over files of the specified type(s) note parens () of set...to are critical syntax
get item -1 of (sort (get files of folder pSourceFolder) by modification date)
log {"Class", class of tSelectedFiles, "length", length of tSelectedFiles}
if length of tSelectedFiles is not 0 then
set inhere to true
copy tSelectedFiles to folder tNewDestFolder
else
set inhere to false
end if
log {"inhere", inhere}
-- copy over the folders, calling this handler recursively
set insub to false
set tFolders to (every folder of pSourceFolder)
repeat with tThisFolder in tFolders
set rresult to my copyItems(tThisFolder as alias, tNewDestFolder as alias)
log {"rresult", rresult}
if rresult then
-- that folder or some sub folder of it is non empty
set insub to true
else
-- that folder is empty and it has no non empty subfolder(s) so delete it
log {tNewDestFolder, "is empty", tThisFolder}
set delpath to ((tNewDestFolder as string) & (name of tThisFolder as string)) as alias
delete delpath
end if
end repeat
log {"inhear", inhere, "insub", insub}
-- return status of this folder and its sub folders if any
if (insub or inhere) then
return true
else
return false
end if
end tell
end copyItems
tell application "Finder"
close windows
open folder "Work3:XX"
end tell
Model: G4 iBook
Browser: Safari 417.8
Operating System: Mac OS X (10.4)
The script you started with selects (in a new Finder window) the most recent file in the chosen folder.
You’ve changed “select” to “get” in your second script. You can’t get a file, you can only read it or examine its properties. I suspect you want its name or a path to it so you can operate on it - true?
Ah, I see - thank you. Yes, I want to locate the particular file (most recent) in the folder and copy it to the new location (which should have the same name as the old location, just in a different path).
So, I need to get the properties of the file (its name) and then copy it to the new location?
Here’s the gist in a nutshell (as a modification of your original):
set theFolder to choose folder with prompt "Select anything for this example"
tell application "Finder"
-- get the latest file
set theFile to (item -1 of (sort (get files of folder theFolder) by modification date))
-- Convert the finder reference to it to a path
set thePath to theFile as string
-- get it's name
set theName to name of theFile
end tell
display dialog "The complete path: " & return & thePath & return & return & "The Name of the file: " & theName
Thanks Adam, that works perfectly for selecting/getting the most recent file from a folder. Can you give me any advice on embedding that logic in some sort of routine that will search through a folder full of sub-folders and copy the most recent file from each folder into new folders? For example, if I have a CD that has three folders on it, and each of those three folders has 2 folders in it and each of those 2 folders has 10 files in it, I would like the script to create an empty folder structure just like the original but having only one file in each of the lowest level folders.
This is the script I use to duplicate a folder tree (with or withour certain file types). I tried replacing the file type code with most recent file code, but the error says it “can’t get last item of {}”
---------------------------------------------------------------------------------------
-- Copy folder tree
-- by Jeff Fischer <jeff@5fischers.org>
--
-- credit to Dan Decker and Robert Metzker for ideas from their scripts
---------------------------------------------------------------------------------------
-- make gFileTypes an empty set to omit copying/moving any files
property gFileTypes : {"psd", "jpg", "gif", "jpeg"}
tell application "Finder"
set tSourceFolder to choose folder with prompt "Choose a folder structure to duplicate"
if tSourceFolder is false then return "User Cancelled"
set tDestFolder to choose folder with prompt "Choose the location for the duplicate structure"
if tDestFolder is false then return "User Cancelled"
my copyItems(tSourceFolder, tDestFolder)
end tell
on copyItems(pSourceFolder, pDestFolder)
tell application "Finder"
set tSourceFolderName to name of pSourceFolder as string
make new folder at pDestFolder with properties {name:tSourceFolderName}
set tNewDestFolder to (folder tSourceFolderName of folder pDestFolder) as alias
-- copy or move over files of the specified type(s)
set tSelectedFiles to (every file of folder pSourceFolder whose name extension is in gFileTypes)
if tSelectedFiles ≠{} then
select (every file of folder pSourceFolder whose name extension is in gFileTypes)
try
-- uncomment the action you want, either copy or move
-- copy the selection to folder tNewDestFolder
move the selection to folder tNewDestFolder
close window (name of folder pSourceFolder as string)
end try
end if
-- copy over the folders, calling this handler recursively
set tFolders to (every folder of pSourceFolder)
repeat with tThisFolder in tFolders
my copyItems(tThisFolder as alias, tNewDestFolder as alias)
end repeat
end tell
end copyItems
Hello again -
I’m sorry to repost but I haven’t been able to make more progress on this task and it would be a huge help to me if someone could point me in the right direction. What I am trying to do is take a CD full of images buried in several levels of folders, duplicate the empty folder structure, and copy just one representative file (the most recent) from each folder into its corresponding duplicated folder. This script (thanks Adam) gets the most recent file from a chosen folder:
set theFolder to choose folder with prompt "Select anything for this example"
tell application "Finder"
-- get the latest file
set theFile to (item -1 of (sort (get files of folder theFolder) by modification date))
-- Convert the finder reference to it to a path
set thePath to theFile as string
-- get it's name
set theName to name of theFile
end tell
display dialog "The complete path: " & return & thePath & return & return & "The Name of the file: " & theName
And I also have a script that successfully duplicates a folder structure with or without certain file types (see below), but I haven’t yet been able to integrate the two scripts. Can anyone help me out, or tell me if there is an easier solution?
Thanks,
John
Here is the folder duplication script:
---------------------------------------------------------------------------------------
-- Copy folder tree
-- by Jeff Fischer <jeff@5fischers.org>
--
-- credit to Dan Decker and Robert Metzker for ideas from their scripts
---------------------------------------------------------------------------------------
-- make gFileTypes an empty set to omit copying/moving any files
property gFileTypes : {}
tell application "Finder"
set tSourceFolder to choose folder with prompt "Choose a folder structure to duplicate"
if tSourceFolder is false then return "User Cancelled"
set tDestFolder to choose folder with prompt "Choose the location for the duplicate structure"
if tDestFolder is false then return "User Cancelled"
my copyItems(tSourceFolder, tDestFolder)
end tell
on copyItems(pSourceFolder, pDestFolder)
tell application "Finder"
set tSourceFolderName to name of pSourceFolder as string
make new folder at pDestFolder with properties {name:tSourceFolderName}
set tNewDestFolder to (folder tSourceFolderName of folder pDestFolder) as alias
-- copy or move over files of the specified type(s)
set tSelectedFiles to (every file of folder pSourceFolder whose name extension is in gFileTypes)
if tSelectedFiles ≠{} then
select (every file of folder pSourceFolder whose name extension is in gFileTypes)
try
-- uncomment the action you want, either copy or move
-- copy the selection to folder tNewDestFolder
move the selection to folder tNewDestFolder
close window (name of folder pSourceFolder as string)
end try
end if
-- copy over the folders, calling this handler recursively
set tFolders to (every folder of pSourceFolder)
repeat with tThisFolder in tFolders
my copyItems(tThisFolder as alias, tNewDestFolder as alias)
end repeat
end tell
end copyItems
Sorry to say that in 20 minutes of trying, jb, that I couldn’t find the magic coercion either, so though I can get partway there I end up with a bunch of empty folders.
In a nutshell for the experts, the problem is to take a CD filled with a nested folder structure containing files and create a copy of the complete structure with only the newest file copied in each folder.
Thank you Adam, thank you jacques for your help on this. I’ve just tried Jacques’ first posted script and it seems to work perfectly (and quickly!) for image files. The second one, however, runs into an error saying that the variable ALL_subfolders is not defined.
Thank you again - this is a big help.
Jaques - my hat is off to you - that is some great work, this particular problem was bugging me all day saturday…I gave up on it a few times. I think the hard part was that there are just so many ways to go about solving this problem - I was having trouble committing to one. I was thinking - would it be easier to duplicate the whole structure then delete everything except the most recent file…or…
Overall, the problem is considerably more difficult than it first seems…
Anyway - again, great work.
Jaques; Let me join ChrisAdmin here - I too spent a lot of time trying (I posted after 20 minutes that I couldn’t do it because I had tried all I could think of by then, but I came back to it several times). Great stuff!