I’ve struggled with this for a couple of days, searched here and the www, still need your help!
I want a script to take a folder full of files and divide it into DVD sized folders for burning to archive. Actually I want the script to be slightly more clever than that…
In the first place I have a script which does what I wish. As you will see it was written with archiving pictures in mind.
property maxFolderSize : 4.3E+9
-- set 'maxFolderSize' to the max size you want, in bytes
-- 610MB = 650000000
tell application "Finder"
-- get the selected files
set sourceFolder to (choose folder with prompt "Pick the folder you want to divide into CD-sized folders:")
set filesToMove to every file of sourceFolder
-- initialize the variables
set fileList to {}
set currentSize to 0
-- now loop through the files
repeat with aFile in filesToMove
-- get the size of the file
set fileSize to physical size of aFile
-- does it fit?
if currentSize + fileSize < maxFolderSize then
-- this file will fit, so add it to the list
set end of fileList to aFile
-- and keep track of how big the current folder is
set currentSize to currentSize + fileSize
else
-- if we get here, the current file will exceed the max size for a folder
-- so move the files we've already identified as fitting into a new folder
-- set up folder name
set firstName to name of item 1 of fileList as string
set folderName to text 1 thru 7 of firstName & " Photos"
-- increment name if necessary
set currentFolderNum to 1
repeat while (exists folder (folderName & " " & currentFolderNum) in sourceFolder)
set currentFolderNum to currentFolderNum + 1
end repeat
-- make a new folder
set destFolder to make new folder in sourceFolder with properties {name:folderName & " " & currentFolderNum}
-- move the files we've identified
repeat with fileToMove in fileList
move fileToMove to destFolder
end repeat
-- now reset our variables to start the next folder list
set fileList to {aFile}
set currentFolderNum to currentFolderNum + 1
set currentSize to fileSize
end if
end repeat
display dialog "Finished!" buttons {"OK"} default button 1
end tell
The result of running this script is you have your original folder containing (say) a couple of sub folders (each 4 GB size) along with the remainder of your files.
What I’d really like to achieve is to put all my pictures into folders. I may end up with two at 4GB and one with only 2GB, that’s okay.
So I guess I nee a “while” somewhere. In English, while there are files in the original folder, move them to a new folder until that folder gets to the maximum folder size, then start a new folder.
This script also seems to take a long time to run - a folder with 1200 files is not unusual. Is there any reason why it creates a list of files before moving them? I did try to make a version of this script which moved a file, then added up the total folder file size but I failed.
I’d appreciate a couple of pointers here, thanks for any help!
Thank you Jacques, that is a big help.
I’m still hoping to get all the files into sub-folders, if anyone can help with that. At the moment if I have 125 files and 50 make the maxFolderSIze I have my original folder with two sub-folders conataining 50 files each plus the last 25 files. I’d like to have three sub-folders, two with 50 files each and the last 25 in their own folder as well.
Perhaps I need to think about using a ‘while’. In English, while I have files to move, move them if the maxFolderSize is reached or else move them anyway. No, maybe I need to count the files so when there are no more files in my filesToMove, all the last files are moved to the destination?
I think I’m looking for tips on how to think about writing AppleScripts - I don’t just want your scripts, I’d like to learn how you found the solution too.
Many thanks!
I’ve modified Jacque’s modification so that all files get put into a folder, evem in that results in a ‘half full’ folder.
(Sorry, Jacque, I changed your names to make more sense for me!)
I’d be interested in feedback fo this.
Thanks!
property maxFolderSize : 4.3E+9
property sourceFolder : missing value
set sourceFolder to (choose folder with prompt "Pick the folder you want to divide into DVD-sized folders:")
tell application "Finder" to set filesToMove to physical size of document files of sourceFolder -- get all size
set {currentSize, reStart, totalFileCount, countDown} to {0, 0, count filesToMove, count filesToMove}
repeat with i from 1 to totalFileCount
if countDown ≤ 1 then
moveFiles(i - reStart)
else
set currentSize to currentSize + (item i of filesToMove)
set countDown to (countDown - 1)
if currentSize > maxFolderSize then
moveFiles(i - 1 - reStart)
set {currentSize, reStart} to {(item i of filesToMove), i - 1}
end if
end if
end repeat
display dialog "Finished!" buttons {"OK"} default button 1
on moveFiles(n)
set currentFolderNum to 1
tell application "Finder" to tell folder sourceFolder
set folderName to text 1 thru 7 of (get name of document file 1)
repeat while (exists item (folderName & " " & currentFolderNum))
set currentFolderNum to currentFolderNum + 1
end repeat
set destFolder to make new folder at it with properties {name:folderName & " " & currentFolderNum}
move (document files 1 thru n) to destFolder
end tell
end moveFiles
Very nice script ! just what I was looking for.
I tried to modify the script but couldn’t get it to work.
Is it possible to set the name of the created sub-folders to parent-folder + number (XXX_001 —>>) ?
Since you have no control over which files to where, it would be nice with a common log-file in ALL the sub-folders, something like this
XXX_001
file
file
file
file
XXX_002
file
file
file
This way you just have to open one log file to search for your file(s)
kenneth
I used to precede the equivalent of Jacque’s script with this (useful when not coming close to filling one DVD as in mailing documents):
property DVD : 4.3E+9
property CD : 6.27 + 8
property sourceFolder : missing value
if button returned of (display dialog "Size for DVD or CD-ROM?" buttons {"DVD", "CD"}) is "DVD" then
set maxFolderSize to DVD
else
set maxFolderSize to CD
end if
-- divide up as Jacques does from here on
I apologize for bumping such an old post, but this script is amazing, and it deserved the 10.6 update I gave it here:
property DVD : 4.3E+9
property CD : 6.27 + 8
on run
--Determine for which type of optical media media we are dividing the folders
if button returned of (display dialog "Size for DVD or CD-ROM?" buttons {"DVD", "CD"}) is "DVD" then
set maxFolderSize to DVD
else
set maxFolderSize to CD
end if
-- Set source folder
set sourceFolder to (choose folder with prompt "Pick the folder you want to divide:")
-- Get file sizes as list
tell application "Finder" to set filesToMove to physical size of document files of sourceFolder -- get all size
--Set up variables:
-- currentSize
-- The size of all the files in this batch together
-- reStart
-- How many folders are left in the main folder
-- totalFileCount
-- Count of all files in the source folder
-- countDown
-- A variable that starts as the count of all the files in the source folder and increments by -1 until it hits zero, in which case the script will end.
set {currentSize, reStart, totalFileCount, countDown} to {0, 0, count filesToMove, count filesToMove}
repeat with i from 1 to totalFileCount
-- If only one file remains, move that file into a new folder by itself.
if countDown ≤ 1 then
moveFiles(i - reStart, sourceFolder)
else
--Incrementally add files until the size is greater than the maxFolderSize, and then go back one. Then tell finder to create a folder and place those files in it.
set currentSize to currentSize + (item i of filesToMove)
set countDown to (countDown - 1)
if currentSize > maxFolderSize then
moveFiles(i - 1 - reStart, sourceFolder)
-- Start over at the next file in the list.
set {currentSize, reStart} to {(item i of filesToMove), i - 1}
end if
end if
end repeat
--Done.
display dialog "Finished!" buttons {"OK"} default button 1
end run
on moveFiles(n, sourceFolder)
--Starting point.
set currentFolderNum to 1
tell application "Finder" to tell folder sourceFolder
set folderName to text 1 thru 5 of (get name of document file 1)
-- Create the next folder in list.
repeat while (exists item (folderName & " " & currentFolderNum))
set currentFolderNum to currentFolderNum + 1
end repeat
set destFolder to make new folder in sourceFolder with properties {name:(folderName & " " & currentFolderNum)}
end tell
-- Instead of using the following code...
--move (document files 1 thru n) to destFolder
-- I'm going to make this use a shell script. Finder keeps freezing when it does this command, so let's see if shell can better handle it.
-- Here is the syntax: sudo mv "folder path to be moved" "destination path"
repeat with i from 1 to n
tell application "Finder"
set thisFile to file 1 of folder sourceFolder
set thisFileName to name of thisFile
set thisFile to POSIX path of (thisFile as alias)
set destinationPath to POSIX path of (destFolder as alias) & thisFileName as string
end tell
set moveFileCommandText to "mv " & quoted form of thisFile & space & quoted form of destinationPath
set moveFileCommand to (do shell script moveFileCommandText)
end repeat
end moveFiles
I found that the script would hang when Finder finished adding the files to the newly-created subfolder (at least in 10.6), so I used a shell script instead of Finder. This does make the application slower, as again we are moving each file one-by-one. But it works, and I don’t have to spend hours upon hours dividing up files when members of my company’s board decide that they want 6 copies of 40gb worth of images and videos from their Ireland vacation.
Thanks much!
_josh
PS I also changed the sourceFolder property to a local variable while I was testing where the bug was, and I never bothered to change it back.
Hi,
This is script is something that I think can be very useful for me but instead of moving individual files to different folders, is there a way to make it check the size of the top folder and if the entire folder would fit onto a CD or DVD move that into a new folder?
I am trying to archive an entire group of files onto the same disk, I don’t want to have them separated.