Batch Convert *.numbers to *.csv AppleScript - applescript

I was looking for a script that would batch convert all *.numbers files in a given folder to *.csv files.
I found the following on GitHub and added an additional line as suggested in the comments suggestion. When I run the script, Numbers launches and opens the test file from the folder specified - but the file is not exported. Numbers just stays open and terminal errors out with:
/Users/Shared/Untitled.scpt: execution error: Numbers got an error: Invalid key form. (-10002)
The script (located in /Users/Shared) has the following permissions:
-rwxr-xr-x
#!/usr/bin/osascript
on run argv
set theFilePath to POSIX file (item 1 of argv)
set theFolder to theFilePath as alias
tell application "Finder" to set theDocs to theFolder's items
-- Avoid export privilege problem
set privilegeFile to (theFolder as text) & ".permission"
close access (open for access privilegeFile)
repeat with aDoc in theDocs
set docName to aDoc's name as text
if docName ends with ".numbers" then
set exportName to (theFolder as text) & docName
set exportName to exportName's text 1 thru -9
set exportName to (exportName & "csv")
tell application "Numbers"
open aDoc
delay 5 -- may need to adjust this higher
tell front document
export to file exportName as CSV
close
end tell
end tell
end if
end repeat
end run
Any suggestions?

Here is what I did and works for me in macOS High Sierra:
In Terminal:
touch numb2csv; open -e numb2csv; chmod +x numb2csv
• This creates an empty ASCII Text file named numb2csv.
• Opens, by default, numb2csv in TextEdit.
• Makes the numb2csv file executable.
Copy and paste the example AppleScript code, shown further below, into the opened numb2csv file.
Save and close the numb2csv file.
In Terminal executed the numb2csv executable file, e.g.:
./numb2csv "$HOME/Documents"
This created a CSV file of the same name as each Numbers document in my Documents folder, not traversing any nested folders.
Example AppleScript code:
#!/usr/bin/osascript
on run argv
set theFilePath to POSIX file (item 1 of argv)
set theFolder to theFilePath as alias
tell application "System Events" to set theDocs to theFolder's items whose name extension = "numbers"
repeat with aDoc in theDocs
set docName to aDoc's name as text
set exportName to (theFolder as text) & docName
set exportName to exportName's text 1 thru -8
set exportName to (exportName & "csv")
tell application "Numbers"
launch
open aDoc
repeat until exists document 1
delay 3
end repeat
tell front document
export to file exportName as CSV
close
end tell
end tell
end repeat
tell application "Numbers" to quit
end run
NOTE: As coded, this will overwrite an existing CSV file of the same name as each Numbers file processed, if they already exist. Additional coding required if wanting to not overwrite existing files
If you receive the Script Error:
Numbers got an error: The document “name” could not be exported as “name”. You don’t have permission.
It is my experience that the Numbers document was not fully opened prior to being exported and that increasing the value of the delay command resolves this issue. This is of course assuming that one actually has write permissions in the folder the target Numbers documents exists.
Or one can introduce an error handler within the tell front document block which, if my theory is right about the target document not being fully loaded before the export, will give additional time, e.g.:
Change:
tell front document
export to file exportName as CSV
close
end tell
To:
tell front document
try
export to file exportName as CSV
close
on error
delay 3
export to file exportName as CSV
close
end try
end tell
Note: The primary example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. See included example directly above.

I was looking for that, unfortunately, that doesn’t work anymore.
This line
tell application "System Events" to set theDocs to theFolder's items whose name extension = "numbers"
Gets the following error:
execution error: Can’t make file "file.numbers" of application "System Events" into the expected type. (-1700)
macOs Big Sur Versio 11.01
automator version 2.10
Numbers version 10.3.5
Inspired by this thread and those articles Exporting Numbers Documents and Get full directory contents with AppleScript
The following code works:
#!/usr/bin/osascript
log "Start"
property exportFileExtension : "csv"
tell application "Finder"
activate
set sourceFolder to choose folder with prompt "Please select directory."
set fileList to name of every file of sourceFolder
end tell
set the defaultDestinationFolder to sourceFolder
repeat with documentName in fileList
log "documentName: " & documentName
set fullPath to (sourceFolder as text) & documentName
log "fullPath: " & fullPath
if documentName ends with ".numbers" then
set documentName to text 1 thru -9 of documentName
tell application "Finder"
set newExportItemName to documentName & "." & exportFileExtension
set incrementIndex to 1
repeat until not (exists document file newExportItemName of defaultDestinationFolder)
set newExportItemName to ¬
documentName & "-" & (incrementIndex as string) & "." & exportFileExtension
set incrementIndex to incrementIndex + 1
end repeat
end tell
set the targetFileHFSPath to ¬
(defaultDestinationFolder as string) & newExportItemName
tell application "Numbers"
launch
open fullPath
with timeout of 1200 seconds
export front document to file targetFileHFSPath as CSV
end timeout
close
end tell
end if
end repeat

user3439894's answer works with a few change:
exists document 1 => number of documents > 0

Related

"Tag and move" Applescript no longer works (High Sierra)

Firstly, let me stress that I have almost no Applescript experience. I'm an Oracle developer by trade, so please assume my knowledge is ZERO so I'd be grateful if you could really dumb down your response.
I wrote this script a year or so ago and it has suddenly stopped working. I'm guessing that a macOS upgrade (on High Sierra) no longer tolerates my probably poorly written script.
on run {input, parameters}
repeat with theFile in input
set FileName to theFile as text
tell application "Finder"
if FileName ends with "-xs.jpg" then
--label value, 0 is no label, 1 Orange, 2 Red, 6 Geen
set the label index of file FileName to 6
move FileName to folder "Macintosh HD:Users:Karla:Pictures:FTP:basket-[xs]:" with replacing
else if FileName ends with "-sm.jpg" then
set the label index of file FileName to 1
move FileName to folder "Macintosh HD:Users:Karla:Pictures:FTP:thumbnails-[sm]:" with replacing
else if FileName ends with "-lg.jpg" then
set the label index of file FileName to 2
move FileName to folder "Macintosh HD:Users:Karla:Pictures:FTP:main-[lg]:" with replacing
else if FileName ends with "-xlg.jpg" then
set the label index of file FileName to 5
move FileName to folder "Macintosh HD:Users:Karla:Pictures:FTP:large-[xlg]:" with replacing
end if
end tell
end repeat
return input
end run
The error I get is "The action "Run AppleScript" encountered an error: "Finder got an error: Can't set file "Macintosh HD:Users:Karla:Pictures:1-IMAGES-TO-DO:image1-lg.jpg" to 2."
If I comment out the tagging and try to just do the move, I get "The action "Run AppleScript" encountered an error: "Finder got an error: Can't get folder "Mackintosh HD:Users:Karla:Pictures:FTP:main-[lg]:"."
Edit:
I have also tried:
on run {input, parameters}
repeat with the_input_file in input
set FileName to POSIX file (the_input_file as alias)
end repeat
return input
end run
but get the error The action "Run AppleScript" encountered the error: "Can't get POSIX file (alias "Macintosh HD:Users:Karla:Pictures:file.jpg")."
Edit again:
So this is where I am. I've created a droplet as follows:
on open theDroppedItems
set lg_folder to POSIX path of "Macintosh HD:Users:Karla:Pictures:test1:"
repeat with current_item_cnt from 1 to count of theDroppedItems
-- load the next file in the_file
set the_current_file to item current_item_cnt of theDroppedItems
move file the_current_file to lg_folder
end repeat
end open
And I still get a -1728 error onthe file. "Can’t get file (alias \"Macintosh HD:Users:Karla:Pictures:test1:test-lg.jpg\")." number -1728 from file (alias "Macintosh HD:Users:Karla:Pictures:test1:test-lg.jpg")
I've spent 2 days on a script that used to work and now inexplicably does not in amongst trying to do my real job. This is supposed to make my life easier.
Try using this code for your droplet...
property folderXS : "Macintosh HD:Users:Karla:Pictures:FTP:basket-[xs]"
property folderSM : "Macintosh HD:Users:Karla:Pictures:FTP:thumbnails-[sm]"
property folderLG : "Macintosh HD:Users:Karla:Pictures:FTP:main-[lg]"
property folderXL : "Macintosh HD:Users:Karla:Pictures:FTP:large-[xlg]"
on run
-- Executed when the script is launched
set theFiles to choose file with prompt ¬
"Choose Files" multiple selections allowed true ¬
without showing package contents
repeat with theFile in theFiles
set FileName to theFile as text
tell application "Finder"
if FileName ends with "-xs.jpg" then
--label value, 0 is no label, 1 Orange, 2 Red, 6 Green
set the label index of file FileName to 6
move FileName to folder folderXS with replacing
else if FileName ends with "-sm.jpg" then
set the label index of file FileName to 1
move FileName to folder folderSM with replacing
else if FileName ends with "-lg.jpg" then
set the label index of file FileName to 2
move FileName to folder folderLG with replacing
else if FileName ends with "-xlg.jpg" then
set the label index of file FileName to 5
move FileName to folder folderXL with replacing
end if
end tell
end repeat
return theFiles
end run
on open theDroppedItems
-- Executed when files are dropped on the script
set lg_folder to "Macintosh HD:Users:Karla:Pictures:test1"
repeat with current_item_cnt from 1 to count of theDroppedItems
set the_current_file to item current_item_cnt of theDroppedItems
tell application "Finder"
move file the_current_file to lg_folder
end tell
end repeat
end open
If anybody comes here as I did, looking for an answer, I can give you an inelegant, hacky way to at least get this working. I had variable this_item which contained an HFS file which I wanted to move into todaysFolder.
Part of the problem is Finder doesn't always know what to do with POSIX paths involving variables, and sometimes you need to use the "my" keyword first. Other time, you need to leave it out. I couldn't figure out the logic.
The following ridiculous code block does it reliably and seems to catch every strange, inscrutable exception.
try
move my (POSIX file (POSIX path of this_item)) to folder (todaysFolder) of disk "Hard Drive" with replacing
on error
try
move (POSIX file (POSIX path of this_item)) to folder (todaysFolder) of disk "Hard Drive" with replacing
on error
try
move (file (POSIX path of this_item)) to folder (todaysFolder) of disk "Hard Drive" with replacing
on error
move (file (this_item)) to folder (todaysFolder) of disk "Hard Drive" with replacing
end try
end try
end try

Applescript: can't make file "xx" into type <<class fsrf>>

I'm trying to get a script working which is able to batch export .mts format video files via quicktime into .mov files in 1080p. The script fails with the following error: "The action “Run AppleScript” encountered an error: “QuickTime Player got an error: Can’t make file (document "00000.MTS") into type «class fsrf».”". I assume this has something to do with using text file paths? Note I'm not experienced with Applescript and would really appreciate any help to get this simple bit of script working. Currently it's in automator as a service:
on run {inputFiles}
if inputFiles is equal to {} then
set inputFiles to (choose file with prompt "Select the file(s) to convert:" with multiple selections allowed without invisibles)
end if
open inputFiles
end run
on open droppedItems
tell application "Finder" to set inputFolder to (container of first item of droppedItems) as Unicode text
set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text
set exportPreset to (choose from list {"Movie", "iPhone", "iPod", "480p", "720p", "1080p"} with prompt "Choose QuickTime Export Preset:") as Unicode text
if exportPreset is equal to "false" then
return
end if
repeat with currentItem in droppedItems
repeat until getProcessPercentCPU("CoreMediaAuthoringSessionHelper") is equal to ""
end repeat
tell application "Finder" to set fileName to name of currentItem as Unicode text
set fileName to text 1 thru ((fileName's length) - (offset of "." in ¬
(the reverse of every character of fileName) as text)) of fileName
convertFile(currentItem, outputFolder & fileName & ".mov", exportPreset)
end repeat
end open
on convertFile(inputFile, outputFile, exportPreset)
tell application "QuickTime Player"
set thisMovie to open inputFile
open for access file thisMovie
close access file thisMovie
export thisMovie in (outputFile) using settings preset exportPreset
close thisMovie
end tell
end convertFile
on getProcessPercentCPU(processName)
do shell script "/bin/ps -xco %cpu,command | /usr/bin/awk '/" & processName & "$/ {print $1}'"
end getProcessPercentCPU
Try changing:
set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text
to:
set outputFolder to POSIX path of (choose folder with prompt "Select output folder:" default location (inputFolder as alias))
and:
convertFile(currentItem, outputFolder & fileName & ".mov", exportPreset)
to:
set outputFile to POSIX file (outputFolder & fileName & ".mov")
convertFile(currentItem, outputFile, exportPreset)
and remove the open for access/close access commands.
Sandboxed apps don't like receiving path strings to open/save commands, but accept alias/POSIX file values okay. (If it still doesn't work then it's some other issue at play, but that's always the first thing to check when you get a filesystem permissions error as you describe.)
The error occurs because thisMovie is a document reference of QuickTime Player and this class cannot be converted / coerced to a file system reference («class fsrf»).
That's what the error message says
Can’t make file (document "00000.MTS") into type «class fsrf»
The Standard Additions command open for access does not support QuickTime Player documents anyway. What is the purpose of the open / close lines?
Note:
as Unicode text as coercion to string is outdated since macOS 10.5 Leopard. It's only used with read and write commands to handle UTF16 encoded text. A coercion to standard AppleScript text is simply written as text. In case of name of currentItem it's redundant anyway because the class of name is always text.

Applescript CS5 and CS6 export with save for web will not work

I am at my wit's end. I have tried all variations to get this script to work. The error I get is Adobe Photoshop CS6 got an error: Can’t get current document. and the highlighted script error is my "export in file newFileName.." block. I've tried putting alias in different positions, using file, not using file. Also I get this error message, but the actual script seems to stop working right after "set docName to name of docRef"
And basically I just copied this code from another script that was working fine and just changed a save this file... to a export this file...
-- set the folders that you want to use
set inputFolder to choose folder with prompt "Choose the folder of images to downsize."
set pathToDesktop to (path to desktop folder as string)
set outputFolder to pathToDesktop & "PhotoshopRetina:"
tell application "Finder"
set filesList to files in folder inputFolder
if not (exists folder outputFolder) then
make new folder at desktop with properties {name:"PhotoshopRetina"}
end if
end tell
with timeout of 86400 seconds
tell application "Adobe Photoshop CS6"
set display dialogs to never
close every document saving no
end tell
repeat with aFile in filesList
tell application "Finder"
-- The step below is important because the 'aFile' reference as returned by
-- Finder associates the file with Finder and not Photoshop. By converting
-- the reference below 'as alias', the reference used by 'open' will be
-- correctly handled by Photoshop rather than Finder.
set theFile to aFile as string
set theFileName to name of aFile
set theFileInfo to info for alias theFile
if kind of theFileInfo is "Adobe Photoshop JPEG file" then
my retinaDisplay(theFile)
end if
end tell
end repeat
end timeout
end
on retinaDisplay(theFile)
tell application "Adobe Photoshop CS6"
open alias theFile
set docRef to the current document
-- Convert the document to a document mode that supports saving as jpeg
if (mode of docRef is not RGB) then
change mode docRef to RGB
end if
tell docRef
set color profile kind to none
end tell
set infoRef to get info of docRef
set docName to name of docRef
set docBaseName to getBaseName(docName) of me
set newFileName to (my outputFolder as string) & docBaseName & ".jpg"
tell current document
export in file newFileName as save for web with options {class:save for web export options, web format:JPEG, embed color profile:false, quality:45} with copying
end tell
close current document without saving
end tell
end retinaDisplay
-- 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
exit repeat
end if
end repeat
return baseName
end getBaseName
end
If I open an image in photoshop I can run this code with no errors.
set f to (path to desktop as text) & "test.jpg"
tell application "Adobe Photoshop CS6"
tell current document
export in file f as save for web
end tell
end tell
However, if I additionally add your "with options" code then I get your error. I don't even know what the "with copying" part is. I don't think that means anything to photoshop. So the problem is not with the "current document". The problem is with your options. You must be doing that part wrong.
Good luck.

Reading file in AppleScript

I'm trying to read an html file into a variable in AppleScript, I have the following code.
tell application "Finder"
set theItems to every file of folder folderName
repeat with theFile in theItems
open for access theFile
set fileContents to (read theFile)
end repeat
end tell
Now I get an error like:
Finder got an error: Can’t make document file "index.html" of folder
[...] of startup disk into type «class fsrf».
What am I doing wrong? I followed this example. Are HTML files not recognized as text?
You have to convert the Finder file objects to aliases or text.
read can be used without separate open or close commands. It reads files as MacRoman without as «class utf8» though. (as Unicode text is UTF-16.)
tell application "Finder" to files of folder "HD:Users:lauri:Sites" as alias list
repeat with f in result
read f as «class utf8»
end repeat
Try:
tell application "Finder" to set theItems to every file of folder folderName
repeat with theFile in theItems
set aFile to POSIX path of (theFile as text)
set fileContents to do shell script "cat " & quoted form of aFile
end repeat
Starting from your original code, this should do it:
set folderPath to choose folder
set someData to ""
tell application "Finder"
set theItems to every file of folder folderPath as list
repeat with theFile in theItems
set theFilePath to theFile as text
if characters -5 thru -1 of theFilePath as string is ".html" then
set theFileHandle to (open for access file theFilePath)
set fileContents to (read theFileHandle)
-- for testing, call some function
set someData to someData & return & processHtml(fileContents) of me
close access theFileHandle
end if
end repeat
-- do something with someData here
return someData
end tell
on processHtml(theData)
-- do something with theData here
return theData
end processHtml
As Lauri wrote, you can add "as «class utf8»" to read the file as UTF8. You could also use "as Unicode text" for UTF16. Personally, I like this, because it is vanilla AppleScript and doesn't need shell scripting.
Using open for access is really doing it the hard way.
If you want to read an HTML file with AppleScript, then the best way to do that is to use AppleScript to tell an HTML editor to read the HTML file for you. That is the fundamental way that AppleScript works. That’s why “tell” is the most important command. That’s why you can accomplish your goal of reading an HTML file into a variable in just 3 lines:
tell application "BBEdit"
open (choose file)
set theHTMLSource to the text of document 1
close document 1
end tell
The following script expands on the above to read an arbitrary number of HTML files from a chosen folder. It works with BBEdit 9, and should also work with BBEdit’s free version, which is called “TextWrangler” and is available in Mac App Store. Or you can fairly easily adapt this script for use with HyperEdit or TextEdit or whatever AppleScript-aware HTML/text editor you prefer to use.
tell application "Finder"
set theFolder to (choose folder)
set theFiles to every file of folder theFolder
set theHTMLSourceList to {}
repeat with theFile in theFiles
if the kind of theFile is equal to "HTML document" then
set theName to the name of theFile
tell application "BBEdit"
open file (theFile as text)
set theSource to the text of document 1
copy {theName, theSource} to the end of theHTMLSourceList
close document 1
end tell
end if
end repeat
end tell
When the above script is finished, the variable “theHTMLSourceList” is populated with the names and source code of the entire folder of HTML documents, like so:
{{name of file 1, source of file 1}, {name of file 2, source of file 2}, {name of file 3, source of file 3}}
… and so on up to an arbitrary number of files. But of course you can have the script return the HTML source to you in whatever way you like. The key point is that an AppleScript-aware HTML editor can both read HTML and set AppleScript variables, so you don’t have to write (and debug and maintain) your own HTML reader in tiny AppleScript.

Create new folder from files name and move files

(This is a new edit from a previous question of mine which achieved -3 votes. Hope this new one has a better qualification)
I need to create an Automator service to organize a high amount of files into folders. I work with illustrator and from each .ai file I create 3 more formats: [name.pdf], [name BAJA.jpg] and [name.jpg], thats 4 files in total
My problem is that during the week I repeat this process to more than 90 different .ai files. So 90 files * 4 is 360 independent files all into the some project folder.
I want to grab all 4 related files into one folder, and set the folder name as the same as the .ai file.
Since all the file names are identical (except one), I thought of telling the finder to grab all the files with the same name, copy the name, create a folder and put this files inside, but I have a file name variant [name LOW.jpg] Maybe I can tell the script to strip that work as an exception.
That way I will all 4 the files unified into one folder.
Thank you in advance
Update: This problem was originally posted back in 2013, now I have a solution. People help me assembled this script to fit my needs.
I added this as a service and assigned a keyboard shurtcut on MacOs.
This is the code:
on run {input, parameters} -- create folders from file names and move
set output to {} -- this will be a list of the moved files
repeat with anItem in the input -- step through each item in the input
set {theContainer, theName, theExtension} to (getTheNames from anItem)
try
# check for a suffix and strip it off for the folder name
if theName ends with " BAJA" then
set destination to (makeNewFolder for (text 1 thru -6 of theName) at theContainer)
else
set destination to (makeNewFolder for theName at theContainer)
end if
tell application "Finder"
move anItem to destination
set the end of the output to the result as alias -- success
end tell
on error errorMessage -- duplicate name, permissions, etc
log errorMessage
# handle errors if desired - just skip for now
end try
end repeat
return the output -- pass on the results to following actions
end run
to getTheNames from someItem -- get a container, name, and extension from a file item
tell application "System Events" to tell disk item (someItem as text)
set theContainer to the path of the container
set {theName, theExtension} to {name, name extension}
end tell
if theExtension is not "" then
set theName to text 1 thru -((count theExtension) + 2) of theName -- just the name part
set theExtension to "." & theExtension
end if
return {theContainer, theName, theExtension}
end getTheNames
to makeNewFolder for theChild at theParent -- make a new child folder at the parent location if it doesn't already exist
set theParent to theParent as text
if theParent begins with "/" then set theParent to theParent as POSIX file as text
try
return (theParent & theChild) as alias
on error errorMessage -- no folder
log errorMessage
tell application "Finder" to make new folder at theParent with properties {name:theChild}
return the result as alias
end try
end makeNewFolder
Hope this helps.
It's a pity you get downvoted as I, personally, enjoy answering these sorts of questions, as it helps me practise and improve my own skills.
Thanks for posting your solution. I think it's a great gesture and others will find it useful.
This script is a bit shorter than and uses "System Events" instead of "Finder", so will be quicker for large numbers of files:
set IllustratorOutputFolder to "/Users/CK/Desktop/example"
tell application "System Events" to ¬
set ai_files to every file in folder IllustratorOutputFolder ¬
whose name extension is "ai"
set Output to {}
repeat with ai_file in ai_files
set AppleScript's text item delimiters to "."
get name of ai_file
get text items of result
set basename to reverse of rest of reverse of result as text
tell application "System Events"
get (every file in folder IllustratorOutputFolder ¬
whose name begins with basename)
move result to (make new folder ¬
in folder IllustratorOutputFolder ¬
with properties {name:basename})
end tell
set end of Output to result
end repeat
return Output -- list of lists of moved files
Just an alternative way of doing things. Not that it's better or worse, but just a different solution.
You could also save this as script.sh (in TextEdit in plain text mode) and run it with bash script.sh in Terminal:
cd ~/Target\ Folder/
for f in *.ai *.pdf *.jpg; do
dir=${f%.*}
dir=${dir% LOW}
mkdir -p "$dir"
mv "$f" "$dir"
done

Resources