Trouble with script moving files to a newly created folder in Applescript - applescript

I am having trouble with what I think is a pretty straightforward task, but cannot seem to get my script to work correctly. I have found a lot of help through the forums with regards to the individual routines used, but it still seems to fail.
In short, what I would like to do is monitor a folder for new files being added. Once a batch of files are added (every other day or so), it will create a folder in another directory with the new folder name being the current date, move those files to the new directory, and then execute a simple bash script which uses the new directory name as an argument.
My script compiles ok, but once files are added it only creates the new folder and nothing else. I appreciate any help.
property the_sep : "-"
on adding folder items to my_folder after receiving the_files
tell application "Finder"
(* First create a new folder with name of folder = current date *)
set the_path to (folder "qa" of folder "Documents" of folder "ehmlab" of folder "Users" of disk "Macintosh HD")
set the_name to (item 1 of my myDate())
set the_name to (the_name & the_sep & item 2 of my myDate())
set the_name to (the_name & the_sep & item 3 of my myDate())
make folder at the_path with properties {name:the_name}
set newDir to the_path & the_name
end tell
(* Next, move the newly added files to the source into the newly created date folder *)
repeat with i from 1 to number of items in the_files
tell application "Finder"
try
set this_file to (item i of the_files)
move file this_file to folder newDir
end try
end tell
end repeat
do shell script "qc.sh " & newDir
end adding folder items to
on myDate()
set myYear to "" & year of (current date)
set myMth to text -2 thru -1 of ("0" & (month of (current date)) * 1)
set myDay to text -2 thru -1 of ("0" & day of (current date))
return {myYear, myMth, myDay}
end myDate

The failure reason are different path styles.
AppleScript uses HFS paths (colon separated).
UNIX uses POSIX paths (slash separated).
The solution is to coerce the HFS path string to POSIX path
do shell script "qc.sh " & quoted form of POSIX path of newDir
This is a shorter version of the script using the shell also for the time stamp and for creating the directory.
on adding folder items to my_folder after receiving the_files
(* Next, move the newly added files to the source into the newly created date folder,
"path to documents" is a relative path to the documents folder of the current user *)
set baseFolder to (path to documents folder as text) & "qa:"
set timeStamp to do shell script "date +%Y-%m-%d"
set newDir to baseFolder & timeStamp
do shell script "mkdir -p " & quoted form of POSIX path of newDir
(* Next, move the newly added files to the source into the newly created date folder *)
repeat with aFile in the_files
tell application "Finder"
try
move aFile to folder newDir
end try
end tell
end repeat
do shell script "qc.sh " & quoted form of POSIX path of newDir
end adding folder items to

Related

AppleScript - Move all the files contained in subfolder to a top folder

I am looking for an edit to the current script. What I need is moving all the files from subfolders (recursively) in to one top folder, however if a file with the same name exist, create a new top-folder and continue there, this is what I have so far:
tell application "Finder"
try
set Random_name to random number from 100 to 9999
set theTopFolder to (choose folder)
set theFiles to a reference to every file of (entire contents of folder theTopFolder)
set theNewFolder to make new folder at theTopFolder with properties {name:"Flattened Files"}
move theFiles to theNewFolder
on error
set theNewFolder to make new folder at theTopFolder with properties {name:"Flattened Files" & Random_name}
move theFiles to theNewFolder
end try
end tell
Just to be clear the structure of the path is not:
Mainfolder/subfolder/file.xxx but Mainfolder/subfolder/sulbfolder2/subfolder3/....100/file.xxx so the script needs to work recursively which it does but it stops when a file exist with the same name
When a file with the same name exist my edit creates a new folder with Flattened Files+random number however when another file with the same name is moved the script stops for an error instead going ahead and creating a new Flattened Files+randonnumber folder. Any ideas?
Thank you
Your script isn't using recursion, it just lets the Finder get all the files. The additional error you are getting is because you are trying to move the whole list of files again.
One solution would be to step through the file items, testing for duplicates as you go, and make new folders as needed. The following script just moves duplicates to added folders (note that an error will still stop the script). I don't know how you are sorting the file list, so I included a line to uncomment to continue moving file items to the added folder.
set theTopFolder to (choose folder)
tell application "Finder"
set theNewFolder to make new folder at theTopFolder with properties {name:"Flattened Files"}
set theFiles to every file of (entire contents of folder theTopFolder) as alias list
repeat with aFile in theFiles
if file ((theNewFolder as text) & (name of aFile)) exists then -- use added folders for duplicates
set counter to 1
set done to false
repeat until done
set suffix to text -2 thru -1 of ("000000" & counter) -- leading zeros for sorting
set alternateFolder to (theTopFolder as text) & "Flattened Files" & space & suffix
tell me to (do shell script "mkdir -p " & quoted form of POSIX path of alternateFolder) -- make new folder as needed
if file (alternateFolder & ":" & (name of aFile)) exists then -- continue to next one
set counter to counter + 1
else
move aFile to folder alternateFolder
# set theNewFolder to folder alternateFolder -- uncomment to continue moving here after a duplicate
set done to true
end if
end repeat
else
move aFile to folder (theNewFolder as text)
end if
end repeat
end tell

Applescript - move files to folder which name begins with first 2 characters of filename

I'd like a little help fine tuning this script. Is it possible to have this script match subfolders based on the first two letters of file? Parent folder would be "Shots" which contains subfolders with unique two letter prefix "BA_Bikini_Atol" which contains subfolders within those folders for the specific shots ba_0020, ba_0030, etc. Would like to move a file, ba_0020_v0002 to the ba_0020 folder by selecting "shots" as the target and the script looks through all the sub folders for a match. Thoughts?
set mgFilesFolder to (choose folder with prompt "Where are the files stored which you would like to move to the destination?")
set mgDestFolder to (choose folder with prompt "Where is the destination folder?")
tell application "System Events"
set folderList to name of folders of mgDestFolder
set fileList to name of files of mgFilesFolder
end tell
repeat with i from 1 to (count folderList)
set folderName to item i of folderList
set filesToMove to {}
repeat with j from 1 to (count fileList)
set filename to item j of fileList
if filename begins with folderName then
set end of filesToMove to alias ((mgFilesFolder as string) & filename)
end if
end repeat
tell application "Finder"
move filesToMove to alias ((mgDestFolder as string) & folderName & ":")
end tell
end repeat
This works in my tests
set mgFilesFolder to (choose folder with prompt "Where are the files stored which you would like to move to the destination?")
set mgDestFolder to (choose folder with prompt "Where is the destination folder?")
(* get the files of the mgFilesFolder folder *)
tell application "Finder" to set fileList to files of mgFilesFolder
(* iterate over every file *)
repeat with i from 1 to number of items in fileList
set this_item to item i of fileList
set this_file_Name to name of this_item as string
(* get the file name code
Using the delimiter "_" break the name into fields of text and returning fields 1 thru 2 . i.e ba_0030 *)
set thisFileCode to (do shell script "echo " & quoted form of this_file_Name & " |cut -d _ -f 1-2")
log thisFileCode
tell application "Finder"
set folderList to ((folders of entire contents of mgDestFolder) whose name starts with thisFileCode)
if folderList is not {} then
move this_item to item 1 of folderList
end if
end tell
end repeat
FROM:
TO:
I've made (with the help from users of this site) the script you're referring to.
I've made similar (more efficient) scripts since then. Most of them depend on ASObjC Runner which you can get here: Download ASObjC Runner
If you have it installed I think the following script will work:
set mgFilesFolder to (choose folder with prompt "Where are the file stored which you would like to move?")
set mgDestFolder to (choose folder with prompt "Where are destination folders?")
tell application "ASObjC Runner"
set mgFiles to enumerate folder mgFilesFolder with recursion without including folders
repeat with mgFile in mgFiles
set mgPrefix to text 1 thru 7 of name of (about file mgFile include only "name")
set mgDest to enumerate folder mgDestFolder match prefix mgPrefix with recursion
manage file mgFile moving into mgDest
end repeat
end tell

Applescript - move files to folder which name begins with first 7 characters of filename

I've got 2 folders
the first folder contains all the files which I'd like to move to a subfolder of the second folder. I'd like to this based on the first 7 characters of both the file & folder names.
So if the first 7 characters of the subfolder in FOLDER 2 matches the first 7 characters of the file in FOLDER 1. The file get's moved into the subfolder of FOLDER 2
Right now I've got an Applescript which works, but it's terribly slow.
Here's the script so far:
set mgFileList to ""
set mgDestFolder to ""
set mgFilesFolder to (choose folder with prompt "Where are the files stored which you would like to move to the destination?")
set mgDestFolder to (choose folder with prompt "Where is the destination folder?")
set folderList to contents of mgDestFolder
tell application "Finder" to set fileList to files of mgFilesFolder
repeat with aFile in fileList
set prefix to getPrefix(name of aFile)
tell application "Finder"
try
set destinationFolder to (1st folder of mgDestFolder whose name begins with prefix)
move aFile to destinationFolder
end try
end tell
end repeat
on getPrefix(aName)
set prefix to text 1 thru 7 of aName
return prefix
end getPrefix
I've only recently got into Applescripting. Can this be done more efficiently within Applescript? I've searched around for a solution which works with a shell script (which I think will probably be a lot faster), but haven't been able to get any of them working.
I'm working on OSX Mountain Lion 10.8.4
--
edit
I see that I've uploaded the wrong version of the script I've managed to put together so far. Above is the script that is working, but it's really slow. Probably because it doesn't use any shell script.
---------------update-------------------
Here is the final script that is working pretty fast right now:
set mgFilesFolder to choose folder with prompt "Where are the files stored which you would like to move to the destination?"
set mgDestFolder to choose folder with prompt "Where is the destination folder?"
tell application "System Events"
set fileList to files of mgFilesFolder whose name does not start with "."
repeat with aFile in fileList
set prefix to my getPrefix(name of aFile)
try
set destinationFolder to (1st folder of mgDestFolder whose name begins with prefix)
move aFile to POSIX path of destinationFolder
end try
end repeat
end tell
on getPrefix(aName)
try
set prefix to text 1 thru 7 of aName
return prefix
on error
return aName
end try
end getPrefix
The Finder is generally a slow program because it does a lot of things on your computer. Therefore you should avoid using it if possible. In your case these tasks can be done using System Events. Try this, maybe it will be faster. Note that you had a couple mistakes in your code which are fixed in this code.
set mgFilesFolder to choose folder with prompt "Where are the files stored which you would like to move to the destination?"
set mgDestFolder to choose folder with prompt "Where is the destination folder?"
tell application "System Events"
set fileList to files of mgFilesFolder whose name does not start with "."
repeat with aFile in fileList
set prefix to my getPrefix(name of aFile)
try
set destinationFolder to (1st folder of mgDestFolder whose name begins with prefix)
move aFile to POSIX path of destinationFolder
end try
end repeat
end tell
on getPrefix(aName)
try
set prefix to text 1 thru 7 of aName
return prefix
on error
return aName
end try
end getPrefix
Not sure how many files you're working with, but I tested this with 10 folders and ~100 files, and it took less than 4 seconds to run. Working with strings is much faster than working with files, so the script gets the files/folders as strings and builds aliases when they're needed.
set mgFilesFolder to (choose folder with prompt "Where are the files stored which you would like to move to the destination?")
set mgDestFolder to (choose folder with prompt "Where is the destination folder?")
--Always use System Events whenever possible. It's WAY faster than Finder.
tell application "System Events"
set folderList to name of folders of mgDestFolder
set fileList to name of files of mgFilesFolder
end tell
repeat with i from 1 to (count folderList)
set folderName to item i of folderList
set filesToMove to {}
repeat with j from 1 to (count fileList)
set filename to item j of fileList
if filename begins with folderName then
set end of filesToMove to alias ((mgFilesFolder as string) & filename)
end if
end repeat
--Can't use system events for moving files. You have to use Finder.
tell application "Finder"
move filesToMove to alias ((mgDestFolder as string) & folderName & ":")
end tell
end repeat
It might be easier to use shell scripting:
cd FOLDER1; for f in *; do d=../FOLDER2/"${f:0:7}"*; [[ -d $d ]] && mv "$f" "$d"; done

Applescript: Create folders/subfolders and move multiple files

I have an Applescript question that is much more complex than I can construct. I have been searching for the past couple of days, and I cannot find any script like this, nor can I find enough information to piece one together with my limited knowledge.
I have multiple files with structured names. Each file has the following name structure:
ttu_collectionname_000001.pdf
ttu_collectionname_000002.mp3
ttu_collectionname_000003.pdf ... etc. (Each of these files are of varying file types.)
There is also a csv metadata file associated with each of the original files.
ttu_collectionname_000001.csv
ttu_collectionname_000002.csv
ttu_collectionname_000003.csv ... etc. (Each of these files are csv files.)
I need to create a folder based on the name of the file with sub and sub-subfolders. Each top-level folder name will be unique in the number sequence. Each sub and sub-subfolder name will be the same for each top-level folder.
The folder structure should look like this:
ttu_collectionname_000001
content
archive
display
metadata
archive
display
ttu_collectionname_000002
content
archive
display
metadata
archive
display
I then need to move the each file to a particular sub-subfolder.
The file ttu_collectionname_000001.pdf would be moved to the ttu_collectionname_000001/content/display folder.
The file ttu_collectionname_000001.csv would be moved to the ttu_collectionname_000001/metadata/display folder.
Try:
set myFolder to "Mac OS X:Users:stark:Main Folder"
tell application "Finder" to set myFiles to folder myFolder's files as alias list
repeat with aFile in myFiles
tell application "System Events" to set {fileName, fileExt} to {name, name extension} of aFile
set baseName to text 1 thru ((get offset of "." & fileExt in fileName) - 1) of fileName
do shell script "mkdir -p " & (quoted form of (POSIX path of myFolder)) & "/" & baseName & "/{\"content\",\"metadata\"}/{\"display\",\"archive\"}"
tell application "System Events"
if fileExt is "pdf" then move aFile to (myFolder & ":" & baseName & ":content:display" as text)
if fileExt is "csv" then move aFile to (myFolder & ":" & baseName & ":metadata:display" as text)
end tell
end repeat
Assuming your files are in the same folder,
this AppleScript:
set pathToFolderOfTTUFiles to (path to the desktop as text) & "TTU:"
tell application "Finder"
set theFiles to every item of folder pathToFolderOfTTUFiles whose name extension is not "csv" and kind is not "Folder"
repeat with theFile in theFiles
set lengthOfExtension to (length of (theFile's name extension as text)) + 1
set fileNameWithoutExtension to text 1 through -(lengthOfExtension + 1) of (theFile's name as text)
set theFolder to make new folder at folder pathToFolderOfTTUFiles with properties {name:fileNameWithoutExtension}
set theContentFolder to make new folder at theFolder with properties {name:"content"}
make new folder at theContentFolder with properties {name:"archive"}
set theContentDisplayFolder to make new folder at theContentFolder with properties {name:"display"}
set theMetadataFolder to make new folder at theFolder with properties {name:"metadata"}
make new folder at theMetadataFolder with properties {name:"archive"}
set theMetadataDisplayFolder to make new folder at theMetadataFolder with properties {name:"display"}
move theFile to theContentDisplayFolder
set pathToCSV to pathToFolderOfTTUFiles & fileNameWithoutExtension & ".csv"
if exists pathToCSV then move pathToCSV to theMetadataDisplayFolder
end repeat
end tell
creates this:

how to use applescript to move files to new folder by extension, keeping subfolder name

Here's what I'm trying to do.
I've got a file structure that contains photos in both JPG and RAW formats. It's a folder called "Photos" with subfolders by date. I'd like to copy just the RAW photos to a new folder, "Photos RAW", but keep the structure by date taken/created.
I can copy just the files using automator or applescript a directory to a new one, but how do I walk the directory tree using applescript so I cover all the subfolders?
Try this. You'll see I used "entire contents" to get the files in the subfolders too.
set extensionToFind to "raw"
set topLevelFolder to (choose folder) as text
set pathCount to count of topLevelFolder
tell application "Finder"
-- get the files
set rawFiles to files of entire contents of folder topLevelFolder whose name extension is extensionToFind
if rawFiles is {} then return
-- setup the folder where the files will be moved
set rawFolder to ((container of folder topLevelFolder) as text) & "Photos_Raw:"
do shell script "mkdir -p " & quoted form of POSIX path of rawFolder
repeat with aFile in rawFiles
set aFileContainer to (container of aFile) as text
if topLevelFolder is equal to aFileContainer then
-- here the file is at the top level folder
set newPath to rawFolder
else
-- here we calculate the new path and make sure the folder structure is in place
set thisFile to aFile as text
set subFolderPath to text (pathCount + 1) thru -((count of (get name of aFile)) + 1) of thisFile
set newPath to rawFolder & subFolderPath
do shell script "mkdir -p " & quoted form of POSIX path of newPath
end if
move aFile to folder newPath
end repeat
end tell

Resources