I've put a script together that moves a predefined number of files into folders that are created sequentially.
It seems somewhat sluggish and being new to this I'm wondering if there's a more elegant do shell script command to aid in this.
set filesPerFolder to 100
set zeroPad to 3
tell application "Finder" to set chosenFolder to (target of Finder window 1) as text
set thisDir to POSIX path of chosenFolder
set folderCount to 1
repeat
set folderCount to zero_pad(folderCount, zeroPad)
set filesToMove to (do shell script "ls -1 " & thisDir & " | wc -l") as integer
if filesToMove is 0 then
return
end if
set theNewFolder to thisDir & folderCount
set asDir to POSIX file theNewFolder
tell application "Finder"
if exists asDir then
-- do nothing
else
do shell script "mkdir -p " & theNewFolder
end if
end tell
tell application "Finder" to set firstFile to first file of folder chosenFolder as alias
set fileToMove to POSIX path of firstFile
set theMove to quoted form of fileToMove & " '" & theNewFolder & "/'"
do shell script "mv -f " & theMove
set filesInFolder to (do shell script "ls -1 " & theNewFolder & " | wc -l") as integer
if filesInFolder ≥ 10 then
set folderCount to folderCount + 1
end if
end repeat
on zero_pad(value, string_length)
set string_zeroes to ""
set digits_to_pad to string_length - (length of (value as string))
if digits_to_pad > 0 then
repeat digits_to_pad times
set string_zeroes to string_zeroes & "0" as string
end repeat
end if
set padded_value to string_zeroes & value as string
return padded_value
end zero_pad
Thanks to Lri's shell command the script is leaner and efficient.
tell application "Finder" to set thisDir to (target of Finder window 1) as string
set rootDirectory to quoted form of POSIX path of thisDir
set counTed to (do shell script "ls -1 " & rootDirectory & " | wc -l") as integer
set filesToMove to (do shell script "ls -2 " & rootDirectory & " | wc -l") as integer
if filesToMove is 0 then
display alert "There are no files in the root of this directory to move."
return
end if
set filesPerFolder to text returned of (display dialog "There are " & counTed & " files in this folder.
How many files would you like to move per folder: " default answer "100")
set fileCount to (do shell script "cd " & rootDirectory & " && i=0;for f in *;do d=$(printf %03d $((i/" & filesPerFolder & "+1)));let i++;mkdir -p $d;mv \"$f\" $d;done")
set filesLeft to (do shell script "ls -2 " & rootDirectory & " | wc -l") as integer
if filesLeft is 0 then
display alert "Completed."
return
end if
i=0;for f in *;do d=$(printf %03d $((i/100+1)));let i++;mkdir -p $d;mv "$f" $d;done
Or using GNU parallel:
ls|parallel -k -N100 x=\$\(printf %03d {#}\)\;mkdir -p \$x\;mv {} \$x
-k keeps the order of the lines and {#} is the sequence number.
Related
Script needs to do the same as a right click > "Compress" in the Finder does.
tell application "Finder"
set myDir to choose folder
set myParentDir to the parent of myDir as alias
set myParentPath to POSIX path of myParentDir
set myDirName to the name of myDir
set myZipName to "'" & myDirName & ".zip'"
set myDirName to the quoted form of myDirName
set myParentPath to the quoted form of myParentPath
set myShellScript to "cd " & myParentPath & " | zip -r " & myZipName & " " & myDirName
tell current application
do shell script myShellScript
end tell
end tell
if I copy the string saved in myShellScript and run it in Terminal it works perfectly but when run from the script editor it fails with the following:
error " zip warning: name not matched: IDA template Folder
zip error: Nothing to do! (try: zip -r IDA template Folder.zip . -i IDA template Folder)" number 12
Any suggestions?
You need to change the pipe | in myShellScript into a newline \n, so:
set myShellScript to "cd " & myParentPath & "\n zip -r " & myZipName & " " & myDirName
NB: The alternative - and the way it will show in Script Editor when it's compiled - is simply to type a literal line feed:
set myShellScript to "cd " & myParentPath & "
zip -r " & myZipName & " " & myDirName
You should replace the | with && - that way the zip command will only run if the cd command succeeds. Like this:
set myShellScript to "cd " & myParentPath & " && zip -r " & myZipName & " " & myDirName
I just updated to Catalina and one of my applescripts no longer works. Wondering if anyone has any ideas as to why? All of the folders selected (single or batch) are on a work server.
The result I get from the Script Editor after selecting a folder is:
-- 'ascr''err '{ '----':'utxt'("Can’t make Can’t make some object
into type some object."), 'errn':-1700,
'erob':'alis'("file:///System/Volumes/Data/data/ARLSCAN2/DIGI/ORIG/FRETSCHEL/Auto/DONE/F2509")
}
--Script Name:
set ScriptName to "jhoveValidation"
--Define user name
set userName to do shell script "whoami"
--Initalize ErrorCount
set errorCount to 0
--Initalize stampCount
set stampCount to 0
-- BEGIN SCRIPT!
--Option to change location mode
set locationModeChoice to display dialog "Would you like to check a single box folder or batch check a directory of box folders?" buttons ["Exit", "Single", "Batch"] default button 3 with title ScriptName with icon caution
set locationModeChoice to button returned of locationModeChoice
if locationModeChoice = "Exit" then
return
end if
if locationModeChoice = "Single" then
set imageDirectory to choose folder with prompt "Select Single Box Folder"
else if locationModeChoice = "Batch" then
set customFolder to choose folder with prompt "Please select a folder of box folders with standard ICT hierarchy:"
set masterFolder to customFolder
end if
-- BEGIN PREFLIGHT
--Populates list of files in finder
set progress description to "jhoveValidation"
set progress additional description to "Loading box and file information..."
set progress total steps to -1
delay 1
if locationModeChoice = "Batch" then
tell application "Finder"
set masterList to folders in masterFolder
if (count of items in masterList) is 0 then
display dialog "ERROR: No files were detected" buttons ["Quit"]
return
end if
end tell
else if locationModeChoice = "Single" then
set masterList to {}
set masterList to masterList & imageDirectory
end if
-- BEGIN IMAGE PROCESSING
set folderCount to count masterList
set folderCounter to 1
repeat with aFolder in masterList
set currentWorkingBox to getLastPathItem(aFolder)
tell application "Finder"
try
set inputFolder to (every folder in aFolder whose name begins with "TIFF") as alias
on error
display dialog "There was an error finding your TIFF folder for box:
" & currentWorkingBox & "
Please place the images you want to inspect in a completed box folder with a TIFF folder inside." buttons ["Quit"]
return
end try
end tell
set progress description to (currentWorkingBox as text) & ": jhoveValidation - Box " & folderCounter & " of " & folderCount
set progress additional description to "Loading TIFF files..."
set progress total steps to -1
tell application "Finder"
try
set filesList to files in inputFolder
set filesCount to count filesList
on error
display dialog "There was an error finding your TIFF folder for box:
" & currentWorkingBox & "
Please place the images you want to inspect in a completed box folder with a TIFF folder inside." buttons ["Quit"]
return
end try
end tell
--***BEGIN LOOP***
--Individual file processing begins here
set loggingCounter to 0
set totalSteps to count filesList
set progress total steps to totalSteps
repeat with aFile in filesList
set loggingCounter to loggingCounter + 1
log loggingCounter
set progress additional description to "Processing file " & loggingCounter & " of " & totalSteps
set progress completed steps to loggingCounter
set AppleScript's text item delimiters to "."
if (the last text item of (aFile as text) is "tif") then
tell application "Finder"
set theFile to aFile as alias
set theFilePath to POSIX path of theFile
log theFilePath
end tell
do shell script "cd ~/Desktop/jhove; ./jhove -c conf/jhove.conf -l SEVERE -o " & (theFilePath as text) & ".txt -m TIFF-hul " & theFilePath
else
end if
end repeat
set progress additional description to "Processing Results & Generating Reports..."
set progress total steps to -1
set currentWorkingFolderPath to POSIX path of (aFolder as alias)
try
do shell script "mkdir " & currentWorkingFolderPath & "VALIDATION"
end try
do shell script "mv " & currentWorkingFolderPath & "TIFF/*.txt " & currentWorkingFolderPath & "VALIDATION"
do shell script "grep -H 'Status' " & currentWorkingFolderPath & "VALIDATION/*.txt | sed 's/:/,/' > " & currentWorkingFolderPath & "VALIDATION/results.csv"
set theResults to {}
set theResults to theResults & paragraphs of (do shell script "cat " & currentWorkingFolderPath & "VALIDATION/results.csv")
set resultsCount to count theResults
set rejectList to {}
set reportStatus to "PASS"
set passCounter to 0
set failCounter to 0
repeat with aResult in theResults
set AppleScript's text item delimiters to ","
log text item 2 of aResult
set thisVar to text item 2 of aResult
if (text item 2 of aResult as text) = " Status: Well-Formed and valid" then
set passCounter to passCounter + 1
log "PASS"
else
set failCounter to failCounter + 1
set rejectList to rejectList & aResult
set reportStatus to "FAIL"
log "FAIL"
end if
end repeat
set totalCount to passCounter + failCounter
if reportStatus = "PASS" then
do shell script "echo \"All files have passed JHOVE Validation.\" > " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \" \" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \"" & passCounter & " files were validated.\" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \" \" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "date >> " & currentWorkingFolderPath & "jhoveReport.txt"
else
do shell script "echo \"!!! ATTENTION - some files have failed JHOVE Validation!!! \" > " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \"" & passCounter & " files passed.\" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \"" & failCounter & " files failed.\" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \" \" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \"----- \" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \"The following have reported failed JHOVE Validation: \" >> " & currentWorkingFolderPath & "jhoveReport.txt"
repeat with aReject in rejectList
do shell script "echo \"" & aReject & "\" >> " & currentWorkingFolderPath & "jhoveReport.txt"
end repeat
do shell script "echo \" \" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "echo \"----- \" >> " & currentWorkingFolderPath & "jhoveReport.txt"
do shell script "date >> " & currentWorkingFolderPath & "jhoveReport.txt"
end if
set folderCounter to folderCounter + 1
end repeat
--***END LOOP***
-- END SCRIPT
-- Function: Returns the document name without extension (if present)
on getBaseName(fName)
set baseName to fName
repeat with idx from 1 to (length of fName)
if (item idx of fName = ".") then
set baseName to (items 1 thru (idx - 1) of fName) as string
end if
end repeat
return baseName
end getBaseName
on getLastPathItem(thePathToParse)
set thePathToParse to (thePathToParse as text)
set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to ":"
set lastPathLength to the number of text items in thePathToParse
set lastPathTarget to lastPathLength - 1
set the lastPathItemItem to text item lastPathTarget of thePathToParse
set AppleScript's text item delimiters to oldDelims
return lastPathItemItem
end getLastPathItem
on getLastPathItemFile(thePathToParse)
set thePathToParse to (thePathToParse as text)
set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to ":"
set the lastPathItemItem to the last text item of thePathToParse
set AppleScript's text item delimiters to oldDelims
return lastPathItemItem
end getLastPathItemFile
With the script we are going to create another script where will be store position of all the elements of the desktop, the created script will be compile and usable to put back in place all the elements previously protected.
/adesktopsave/deskico.txt it is the temporary file which will be of use to the compilation.
/adesktopsave/savedicoposition.scpt It is the script of saving that is compiled to be used with applescrit
All the names used here exist that just for the example. These names have no particular property.
It is just necessary to plan to create a folder before using this script. Here it is:
/adesktopsave
Something else, end of line (\n) after " try
"
also " end try
"
and & "}
")
Are very important to respect so that the text is usable.
tell application "Finder" to set theList to {name, desktop position} of items of desktop
try
do shell script "rm -f /adesktopsave/deskico.txt"
do shell script "echo tell application " & quoted form of (quote & "Finder" & quote) & return & " >>/adesktopsave/deskico.txt"
end try
set n to (count (first item of theList))
repeat with i from 1 to n
set inp to do shell script "echo " & quoted form of (item i of first item of theList)
set xy to (item i of second item of theList)
set AppleScript's text item delimiters to ","
set xyz to do shell script "echo " & xy
set wxyz to ("{" & xyz & "}
")
set ligne to "try
" & "set desktop position of item " & quoted form of (quote & inp & quote) & " of desktop to " & quoted form of (wxyz) & "end try
"
set ligne to do shell script "echo " & ligne & " >>/adesktopsave/deskico.txt"
end repeat
do shell script "echo " & "end tell" & return & " >>/adesktopsave/deskico.txt"
display dialog "Do you want to save your icons in their current location?" buttons {"Cancel", "Save"} default button 2 with title "Save the positions of icons"
if (button returned of result) is "Cancel" then
set n to do shell script "echo " & n
else
do shell script "osacompile -o " & "/adesktopsave/savedicoposition.scpt" & " /adesktopsave/deskico.txt"
end if
return n
We can lighten the script to its simplest expression. At the risk of having errors can be.
set ligne to ""
do shell script "mkdir -p /adesktopsave"
tell application "Finder" to set {names, positions} to {name, desktop position} of items of the desktop
set ligne to "tell application \"Finder\"
"
set n to (count names)
set AppleScript's text item delimiters to ","
repeat with i from 1 to n
set ligne to ligne & ("try
" & "set desktop position of item " & (quote & item i of names & quote) & " to {" & item i of positions & "}
end try
")
end repeat
set ligne to ligne & ("end tell" & return)
display dialog "Do you want to save your icons in their current location?" buttons {"Cancel", "Save"} default button 2 with title "Save the positions of icons"
if (button returned of result) is "Cancel" then
set n to do shell script "echo " & n
else
do shell script "osacompile -o " & "/adesktopsave/savedicoposition.scpt -e " & quoted form of ligne
end if
set AppleScript's text item delimiters to ""
tell application "Finder" to open POSIX file "/adesktopsave/savedicoposition.scpt"
return n
Working on a script that downloads files and places them in a folder for for automated installation. This is the first time I've created an "on" sub-routine and I'm having issues with resolving the path to check if the file exists. The process uses a Terminal window to monitor the download status.
set theContentPath to POSIX path of (choose folder)
set toInstall to (theContentPath & "ToInstall/")
set inStalled to (theContentPath & "Installed/")
set theTemp to (theContentPath & "theTemp/")
do shell script "mkdir -p " & quoted form of toInstall
do shell script "mkdir -p " & quoted form of inStalled
do shell script "mkdir -p " & quoted form of theTemp
set theList to {"http://url1.pkg",
"http://url2.pkg",
"http://url3.pkg",
"http://url4.pkg",
"http://url5.pkg",
"http://url6.pkg"}
repeat with x from 1 to (count theList)
--display dialog item x of theList
set thisOne to item x of theList
getFileIfNeeded(thisOne, toInstall, theTemp)
end repeat
on getFileIfNeeded(theFileToGet, whereToSave, tempFiles)
set AppleScript's text item delimiters to "/"
set theItems to text items of theFileToGet
set theFile to item 5 of theItems
set theFileCheck to whereToSave & theFile
set theURL to quoted form of theFileToGet
tell application "Finder"
if not (exists file theFileCheck) then
tell application "Terminal"
if (count of windows) is 0 then
activate
end if
do script "cd " & quoted form of tempFiles & " ; curl -O " & theURL in front window
do script "mv " & quoted form of tempFiles & "*.pkg " & quoted form of whereToSave in front window
end tell
end if
end tell
end getFileIfNeeded
Tried adding the following set theFileCheck2 to (POSIX file theFileCheck) as string but the results are not what I expected as the file still get's downloaded.
Here's the routine with my attempt to get the path right.
on getFileIfNeeded(theFileToGet, whereToSave, tempFiles)
set AppleScript's text item delimiters to "/"
set theItems to text items of theFileToGet
set theFile to item 5 of theItems
set theFileCheck to whereToSave & theFile
set theURL to quoted form of theFileToGet
tell application "Finder"
set theFileCheck2 to (POSIX file theFileCheck) as string
if not (exists file theFileCheck2) then
tell application "Terminal"
if (count of windows) is 0 then
activate
end if
do script "cd " & quoted form of tempFiles & " ; curl -O " & theURL in front window
do script "mv " & quoted form of tempFiles & "*.pkg " & quoted form of whereToSave in front window
end tell
end if
end tell
end getFileIfNeeded
This should fix it.
It targets "System Events" instead of "Finder", a lot of the functionality previously in the Finders dictionary has been shifted to System Events over the last several years.
Also i simplified the part that extracts theFile, you can use the 'last' keyword in this case instead of a hard coded number.
on getFileIfNeeded(theFileToGet, whereToSave, tempFiles)
set AppleScript's text item delimiters to "/"
set theFile to the last text item of theFileToGet
set theFileCheck to whereToSave & theFile
set theURL to quoted form of theFileToGet
tell application "System Events"
if not (exists file theFileCheck) then
tell application "Terminal"
if (count of windows) is 0 then
activate
end if
do script "cd " & quoted form of tempFiles & " ; curl -O " & theURL in front window
do script "mv " & quoted form of tempFiles & "*.pkg " & quoted form of whereToSave in front window
end tell
end if
end tell
end getFileIfNeeded
In the past I had created an applescript for datedspace but which is not running anymore.
I would like to create an applescript that would look inside a folder ~/Documents/pool/ or ~/Downloads.
Let's say we are on February 7, 2011.
Check if the ~/Documents/2011/02/07/ exists
If not create ~/Documents/2011/02/07/
Move the files and/or folders inside ~/Documents/pool/ to ~/Documents/2011/02/07/
Bonus
Create a text file in ~/Documents/2011/ with the name index.mdown and containing the following format
# Index 2011
## January
[…]
## February
* 2011-02-07: Foo.jpeg
* 2011-02-07: Bar/
Lead or incomplete solutions are welcome.
Previous script
-- Script to automaticaly save documents in a date space.
-- Karl Dubost - http://www.la-grange.net/ - <karl#*******> - 2001 ©
-- Feel free to distribute it and modify it
-- Feel free to send me improvements
-- ********************************************************
-- Version 1.1 2001-03-30
-- Add control on existence of folders year and month
-- Make it more general based on Startup Disk
-- Version 1.0 2001-03-29
-- Creation of the code
-- Thanks to Bill Briggs
-- http://maccentral.macworld.com/columns/briggs.shtml
-- ********************************************************
on adding folder items to this_folder after receiving added_items
tell application "Finder"
set yourDisk to name of startup disk as string
end tell
set todaysDate to (current date)
set {d, m, y} to {day, month, year} of todaysDate
set monthList to {January, February, March, April, May, June, ¬
July, August, September, October, November, December}
repeat with i from 1 to 12
if m = (item i of monthList) then
set monthString to text -2 thru -1 of ("0" & i)
exit repeat
end if
end repeat
set y to y as string
set dayString to text -2 thru -1 of ("0" & d)
set dayString to dayString as string
set datedFolder to yourDisk & ":Documents:" & y & ":" & monthString & ":" & dayString & ":" as string
set monthFolder to yourDisk & ":Documents:" & y & ":" & monthString & ":" as string
set yearFolder to yourDisk & ":Documents:" & y & ":" as string
set rootFolder to yourDisk & ":Documents:" as string
tell application "Finder"
if (folder datedFolder exists) then
repeat with oneFile in added_items
move oneFile to folder datedFolder
end repeat
else if not (folder yearFolder exists) then
make new folder at folder rootFolder with properties {name:y}
else if not (folder monthFolder exists) then
make new folder at folder yearFolder with properties {name:monthString}
else
make new folder at folder monthFolder with properties {name:dayString}
repeat with oneFile in added_items
move oneFile to folder datedFolder
end repeat
end if
end tell
end adding folder items to
I hope this will be good enough :-) :
With the help of some basic command line applications it creates subfolders in your ~/Documents folder (mkdir -p: it will not overwrite existing directories!), moves files there (mv -n: not overwriting files with the same name), then creates monthly logfiles containing the names of addedItems and finally a index.mdown file with all monthly logfiles which should look like this:
2011/01/03: testfile9
2011/02/01: testfile10
2011/02/07: testfile11
Now go ahead and attach it to your folder, give it a try! (maybe uncomment baseFolder and change it to /tmp/test or something, or to POSIX path of thisFolder, if you want it to clean up the folder it´s attached to.)
property dateFormatForFolder : "+%Y/%m/%d"
property dateFormatForMonthlyLog : "+%Y/%m/"
property dateFormatForYearlyLog : "+%Y/"
on adding folder items to thisFolder after receiving addedItems
set baseFolder to POSIX path of (path to documents folder)
set todaysFolder to do shell script "/bin/date '" & dateFormatForFolder & "'"
set monthsFolder to do shell script "/bin/date '" & dateFormatForMonthlyLog & "'"
set yearsFolder to do shell script "/bin/date '" & dateFormatForYearlyLog & "'"
set fullPath to baseFolder & todaysFolder
createFolder(fullPath)
repeat with i from 1 to number of items in addedItems
set oneItemsPath to (quoted form of POSIX path of item i of addedItems)
try
moveToFolder(fullPath, oneItemsPath)
end try
set fileName to name of (info for item i of addedItems)
set logThis to todaysFolder & ": " & fileName
do shell script "echo " & logThis & " >> " & baseFolder & monthsFolder & "log.txt"
end repeat
do shell script "find " & baseFolder & yearsFolder & " -type f -name 'log.txt' -print0 | xargs -0 cat > " & baseFolder & yearsFolder & "index.mdown"
end adding folder items to
on createFolder(fullPath)
do shell script "/bin/mkdir -p " & quoted form of fullPath
end createFolder
on moveToFolder(fullPath, oneItemsPath)
do shell script "/bin/mv -n " & oneItemsPath & " " & fullPath
end moveToFolder