Applescript for batch-converting text delimited .txt to .xls - applescript

Each day, I'm delivered ~5 .txt data files delimited with "^". Manual steps taken to convert each to spreadsheet:
• Open .txt file in Excel
• Text-To-Columns
• Run through the delimiting wizard
Would love to have an applescript or applet to drop the 5 files into. A Google Sheets script would be even more magical. Thanks in advance for any guidance.
Sample data:
developer^project^lender^uuid^id^remarks^code^transfer_date
1500^1502^009^f1e97d20-b311-41cf-a40f-59db90b25ba8^73890^a10a46e8-bca8-4f0d-8938-8f2803a8bf90^9^2018-10-23 10:17:23.0
1500^1502^009^5dfc330d-0b9a-407d-a9e6-36895207b89e^74460^4a9c046a-a544-45b5-a627-f567b94f2b87^9^2018-10-23 10:17:25.0
1500^1502^009^d3295a4a-235d-4b9d-8775-5c079571193e^74901^de8f7b66-0c14-450f-8f29-c30c9a8329fa^9^2018-10-23 10:17:26.0

You'll need to change the file paths supplied at the start of the script inside the variable CSVFiles. The Excel file is saved in the same directory as the CSV file from which it sources its data, and uses the same filename, appending the extension ".xlsx" to it.
use Excel : application "Microsoft Excel"
use scripting additions
# Used to split the CSV data into columns
property text item delimiters : {"/", "^"}
# These represent the 5 CSV files you are sent on a given day
set CSVFiles to {¬
"/Users/CK/Desktop/sample.csv", ¬
"/Users/CK/Desktop/sample2.csv", ¬
"/Users/CK/Desktop/sample3.csv", ¬
"/Users/CK/Desktop/sample4.csv", ¬
"/Users/CK/Desktop/sample5.csv"}
repeat with fp in CSVFiles
try
# Make sure CSV file exists
fp as POSIX file as alias
on error
false
end try
set f to the result
if f ≠ false then
# Obtain directory and filename to use for saving Excel document
set [dirpath, filename] to [¬
text items 1 thru -2 of POSIX path of f as text, ¬
text item -1 of POSIX path of f]
# Read the CSV data into an array (list)
set CSVrows to paragraphs of (read f)
if the last item of CSVrows = "" then ¬
set CSVrows to items 1 thru -2 of CSVrows
repeat with r in CSVrows
set r's contents to text items of r
end repeat
set n to count CSVrows
set cellrange to "A1:H" & n
set colHrange to "H2:H" & n
# Create the Excel sheet
make Excel new document
set S to active sheet of window 1 of Excel
# Copy in CSV data
set value of range cellrange to CSVrows
# Format the last column to handle dates & times
set number format of range colHrange to "dd/mm/yyyy hh:mm:ss"
# Save & Close
save S in (dirpath & "/" & filename & ".xlsx")
Excel's (close front window)
end if
end repeat
If you had a dedicated folder into which you saved your newly received CSV files, then this line:
set CSVFiles to {¬
"/Users/CK/Desktop/sample.csv", ¬
"/Users/CK/Desktop/sample2.csv", ¬
"/Users/CK/Desktop/sample3.csv", ¬
"/Users/CK/Desktop/sample4.csv", ¬
"/Users/CK/Desktop/sample5.csv"}
could be replaced with this line:
tell app "System Events" to set CSVFiles to the POSIX path of ¬
every file in the folder named "/Path/To/Folder for CSV files" whose ¬
name extension = "CSV"
Then, all you'd need to do is remove yesterday's CSV files from that directory (you don't want them being processed a second time); transfer in today's CSV files; then execute the script.
Alternatively, as you stated in your question, you can create an applet onto which CSV files can be dropped and processed. This would be done via Automator.

Related

Applescript to create folders and download files from weblink to those created folders based on .CSV values

In my example .CSV file, I have a column A with the following values: 2,2,5,5,5. In column B are hyperlinks to corresponding files that require downloading: http://example.com/2A.pdf, http://example.com/2B.pdf, http://example.com/5A.pdf, http://example.com/5B.pdf, http://example.com/5BC.pdf. Having difficulty creating an applescript that creates the DL folder (based on the non-unique column A value) and applies the DLs of any corresponding row to the appropriate folder. Any help would be greatly appreciated! TIA.
From your description, I am assuming the CSV file looks something like this:
2, http://example.com/2A.pdf
2, http://example.com/2B.pdf
5, http://example.com/5A.pdf
5, http://example.com/5B.pdf
5, http://example.com/5BC.pdf
and that the file 2A.pdf should end up in a directory called 2.
Assuming I have interpreted this correctly, here is the AppleScript that will achieve this (replace /Path/To/Save/Folder/ with the full path to the folder where these new files and folders will be downloaded, and /Path/To/File.csv to the full path of the CSV file):
-- Note: The ending / is essential in BaseDir
set BaseDir to POSIX file "/Path/To/Save/Folder/"
set rows to every paragraph of (read "/Path/To/File.csv")
set AppleScript's text item delimiters to {"/"}
set [TopDir, BaseFolder] to [text items 1 thru -3, text item -2] of ¬
POSIX path of BaseDir
-- Create initial base folder if it doesn't exist
tell application "Finder" to if not (exists BaseDir) then ¬
make new folder in (TopDir as text as POSIX file) ¬
with properties {name:BaseFolder}
-- This will prevent EOF-related errors
-- Thanks to #user3439894 for highlighting the need for this
set rows to reverse of rows
if the number of words of the first item in rows is 0 ¬
then set rows to the rest of rows
repeat with row in rows
set [N, |url|] to [first word, text items -2 thru -1] of row
-- Create folder into which file will be downloaded
tell application "Finder" to if not (exists [BaseDir, N] as text) then ¬
make new folder in BaseDir with properties {name:N}
-- This is the shell command that downloads the file
-- e.g. "cd '/Users/CK/Desktop/example.com/5'; curl example.com/5BC.pdf \
-- remote-name --silent --show-error"
set command to ("cd " & ¬
quoted form of POSIX path of ([BaseDir, N] as text) & ¬
"; curl " & |url| as text) & ¬
" --remote-name --silent --show-error"
-- Run the shell command
do shell script command
end repeat
-- Open folder in Finder upon completion of downloads
tell application "Finder"
activate
open BaseDir
end tell
I should highlight that this is not a robust script intended for general use that would work across situations, but rather an example script that is tailored specifically to the case described. If your CSV file differs even slightly from my assumed format, errors are likely to occur.

Merging files in Applescript

I am trying to do below in AppleScript.
Concatenate/Merge all *.xxx files found in a particular folder into one new file
Each file contains a header. Strip header from all but 1st file before merging.
Add a footer text to the merged file.
This sounds relatively simple in other languages but I am a beginner to applescript. Any help to find a direction would be appreciated.
TIA
AnuRV
Try this, you are prompted to choose a base folder and a destination file name.
Important: Use a destination location outside the base folder to avoid the file to be included in the merging process.
I assume that your tsv file type is a typo and you mean csv.
If not, change all occurrences of csv in the script.
The text delimiter is linefeed (0A), if you need return (0D) change the occurrence of linefeed to return.
set baseFolder to choose folder
set destinationFile to choose file name with prompt "Choose destination file name" default name "merged.csv"
tell application "Finder" to set tsvFiles to (files of baseFolder whose name extension is "csv") as alias list
set text item delimiters to linefeed
try
set fileDescriptor to open for access destinationFile with write permission
repeat with i from 1 to (count tsvFiles)
set theFile to item i of tsvFiles
set theText to paragraphs of (read theFile as «class utf8»)
if i = 1 then
write (theText as text) to fileDescriptor as «class utf8»
else
write ((items 2 thru -1 of theText) as text) to fileDescriptor as «class utf8»
end if
end repeat
close access fileDescriptor
on error
try
close destinationFile
end try
end try
set text item delimiters to {""}

AppleScript to convert NEF to JPG preserving Creation Date/Time

I have a Nikon camera that outputs great NEF raw files, and not so great JPEG files. I can use the Preview app that came with my Mac OSX 10.6.8 (Snow Leopard) to simply open a NEF and SaveAs JPEG to create a file about 1/6 the size that is virtually indistinguishable from the original NEF.
[EDIT] Here is the final script that works as desired, with comments and some error testing:
(*
AppleScript to convert Nikon raw NEF files into much smaller JPG files.
The JPG files will inherit the file date and time of the source NEF files.
Note that any JPG files in the target folder that have the same name
as a NEF file in that folder, will be overwritten.
*)
-- User selects target folder with NEF files to convert and save there.
set theImageFolder to choose folder with prompt "
Select a folder containing fileⁿ.NEF images to
convert into JPEG images and SaveAs: fileⁿ.JPG"
set theOutputFolder to theImageFolder
-- Finder locates NEF files, ignoring other file types in the target folder.
tell application "Finder"
set theImages to every file of theImageFolder whose name extension is "NEF"
end tell
-- Image Events app processes the images.
tell application "Image Events"
launch
repeat with a from 1 to length of theImages
-- Get file name as text string.
set theImage to file ((item a of theImages) as string)
-- Get date/time of source NEF file.
tell application "Finder" to set fileTimestamp to creation date of theImage
set theImageReference to open theImage
tell theImageReference
set theImageName to name
-- Detect the .NEF extension to replace with .JPG on output.
set savedDelimiters to AppleScript's text item delimiters
-- Split filename string into list, using "." as a delimiter.
set AppleScript's text item delimiters to {"."}
set delimitedList to every text item of theImageName
-- Remove the .NEF extension from the list, if it was there.
ignoring case
--Process only NEF files.
if last item of delimitedList is "NEF" then
set filenameList to items 1 thru -2 of delimitedList
set theImageName to filenameList as string
end if
end ignoring
-- Restore delimiters to default in case it had previously been changed.
set AppleScript's text item delimiters to savedDelimiters
-- Construct full path of file to save, with JPG as output file extension.
set saveImageName to ((theOutputFolder as string) & theImageName & ".JPG")
-- Check if a file with the output JPG file name is already present in the target folder.
tell application "Finder"
if exists file saveImageName then
-- Abort script if user doesn't want to overwrite this file and continue.
beep
if button returned of (display dialog " An identical JPG file is already at:
" & saveImageName & "
Would you like to:" buttons {"Replace it and continue", "Abort"} default button "Abort") is "Abort" then exit repeat
end if
end tell
-- SaveAs the file in JPEG format, leaving the source NEF file unmodified.
set saveImageName to save in saveImageName as JPEG
--Match the output JPG file date/time to that of the NEF source file.
tell application "Finder" to set modification date of saveImageName to fileTimestamp
end tell
end repeat
end tell
tell application "Finder"
display alert "Done. Duplicated selected NEF files in
" & theOutputFolder & "
as JPGs with dates/times matching NEFs."
end tell
Below was my initial attempt to create an AppleScript to spare me the hours it would take to do this manually with the Preview app on my hundreds of NEF files. It works, but the helpful folks on this website helped me to greatly improve it. As you can see from the initial user prompt, I wanted to prompt the user only in the event that an existing JPG file will be replaced. I also wanted to have the output file names be n.JPG rather than n.NEF.jpg and have the output JPG file inherit the original NEF file's Creation Date & Time. I welcomed any suggestions, though since I'd already come this far my preference was to refrain from adding shell scripts and do it all with AppleScript if possible.
set theImageFolder to choose folder with prompt "Note: This script will replace any existing files in the selected folder matching
the name of a NEF file and end in a JPG extension with a new file of that name.
For example, X.NEF will create X.JPG and replace any existing file named X.JPG
that was already in the selected folder (not in any other folders). To begin now,
Select a folder with NEF images to convert into JPEG images:"
set theOutputFolder to theImageFolder
tell application "Finder"
set theImages to every file of theImageFolder whose name extension is "NEF"
end tell
tell application "Image Events"
launch
repeat with a from 1 to length of theImages
set theImage to file ((item a of theImages) as string)
set theImageReference to open theImage
tell theImageReference
set theImageName to name
save in ((theOutputFolder as string) & theImageName & ".JPG") as JPEG
end tell
end repeat
end tell
tell application "Finder"
display alert "Done. All NEF files in the selected folder have been duplicated in JPEG format."
end tell
Thank you so much, Atomic Toothbrush!
I can't seem to insert a blank line to a Comment or mark as Code here without it saving the Comment, so here's a followup as an Answer. Really it's more of a revised Question. :}
Seems to me it's very close to working as hoped. I replaced the code inside the Repeat section with the fascinating snippet you suggested, though I don't yet fully understand the tricks it's doing. With one file in the target folder the script aborts highlighting the word "alias" with this message:
error "File Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG wasn’t found." number -43 from "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
With two files in the target folder and the "as alias" removed, it creates DSC_2070.JPG just fine but doesn't change the mod date and aborts with this message:
error "Can’t set modification date of \"Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG\" to date \"Wednesday, August 28, 2013 1:03:29 PM\"." number -10006 from modification date of "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
If I run it once to create the JPG file as above, then add the "as alias" back in and run it again it does change the date (for both creation and modification!) to match the source file but then aborts highlighting the last Tell inside the Repeat with this message:
error "File Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG wasn’t found." number -43 from "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
Looks like it's remembering the last file processed because if I rename the file, remove the "as alias" and run it again it aborts highlighting that same last Tell line inside the Repeat with this message referencing the file name that's no longer in the folder:
error "Can’t set modification date of \"Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG\" to date \"Wednesday, August 28, 2013 1:14:19 PM\"." number -10006 from modification date of "Art:Users:me:Desktop:scriptTest:-file:DSC_2070.JPG"
Complete script with Repeat string inserted as tested above:
set theImageFolder to choose folder with prompt "Select a folder with NEF images to convert into JPEG images:"
set theOutputFolder to theImageFolder
tell application "Finder"
set theImages to every file of theImageFolder whose name extension is "NEF"
end tell
tell application "Image Events"
launch
repeat with a from 1 to length of theImages
set theImage to file ((item a of theImages) as string)
tell application "Finder" to set fileTimestamp to creation date of theImage
set theImageReference to open theImage
tell theImageReference
set theImageName to name
set savedDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"."}
set delimitedList to every text item of theImageName
ignoring case
if last item of delimitedList is "NEF" then
set filenameList to items 1 thru -2 of delimitedList
set theImageName to filenameList as string
end if
end ignoring
set AppleScript's text item delimiters to savedDelimiters
set saveImageName to ((theOutputFolder as string) & theImageName & ".JPG") as alias
save in saveImageName as JPEG
tell application "Finder" to set modification date of saveImageName to fileTimestamp
end tell
end repeat
end tell
tell application "Finder"
display alert "Done. All NEF files in the selected folder have been duplicated in JPEG format with modification date and time changed to match the NEF source file."
end tell
You could also use sips to convert the images and touch -r to change the modification (and creation) times:
for f in *.nef; do jpg="${f%nef}jpg"; sips -s format jpeg -s formatOptions 90 "$f" -o "$jpg"; touch -r "$f" "$jpg"; done
touch -r normally changes only the modification and access times, but it also changes the creation time if the target time is before the original creation time.
If the files have different creation and modification times, you can use SetFile and GetFileInfo:
SetFile -m "$(GetFileInfo -m "$f")" "$jpg"; SetFile -d "$(GetFileInfo -d "$f")" "$jpg"
-m changes the modification time and -d changes the creation time. SetFile and GetFileInfo are part of the command line tools package that can be downloaded from developer.apple.com/downloads or from Xcode's preferences.
From the filename point of view, it sounds like you just need to strip the .NEF extension from the filename. You can do this by turning the filename string into a list, using "." as a delimiter, remove the last item from the list, then reassemble the list to the filename string. I think this should do it (inserted into "repeat" block):
set theImage to file ((item a of theImages) as string)
tell application "Finder" to set fileTimestamp to creation date of theImage
set theImageReference to open theImage
tell theImageReference
set theImageName to name
set savedDelimiters to AppleScript's text item delimiters
-- Split filename string into list, using "." as a delimiter
set AppleScript's text item delimiters to {"."}
set delimitedList to every text item of theImageName
-- Remove the .NEF extension from the list, if it was there
ignoring case
if last item of delimitedList is "NEF" then
set filenameList to items 1 thru -2 of delimitedList
set theImageName to filenameList as string
end if
end ignoring
-- Restore delimiters to default in case of other users
set AppleScript's text item delimiters to savedDelimiters
-- Construct full path of file to save
set saveImageName to ((theOutputFolder as string) & theImageName & ".JPG")
-- Check for file existence
tell application "Finder"
if exists file saveImageName then
-- Check with user - skip to the next file if user doesn't want to overwrite
if button returned of (display dialog saveImageName & " already exists. Overwrite?" buttons {"Yes", "No"}) is "No" then exit repeat
end if
end tell
-- Save the file
set saveImageName to save in saveImageName as JPEG
-- Fiddle the timestamp of the saved file
tell application "Finder" to set modification date of saveImageName to fileTimestamp
end tell
Note I don't think you can easily change t)he creation date on the .JPG file (it is a r/o property in the finder dictionary. The best I can do is set the modification date of the .JPG file to the creation date of the .NEF file.

Use Automator/Applescript to crop filenames after certain character?

I have a folder containing about 5000 files with names like:
Invoice 10.1 (2012) (Digital) (4-Attachments).pdf
Carbon Copy - Invoice No 02 (2010) (2 Copies) (Filed).pdf
01.Reciept #04 (Scanned-Copy).doc
I want to rename these files by removing everything from the first bracket onwards, so they look like this:
Invoice 10.1.pdf
Carbon Copy - Invoice No 02.pdf
01.Reciept #04.doc
I have found lots of scripts that will remove the last x letters, but nothing that will crop from a particular character.
Ideally I would like to use Automator, but I'm guess this might too complex for it. Any ideas?
Try:
set xxx to (choose folder)
tell application "Finder"
set yyy to every paragraph of (do shell script "ls " & POSIX path of xxx)
repeat with i from 1 to count of yyy
set theName to item i of yyy
set name of (file theName of xxx) to (do shell script "echo " & quoted form of theName & " | sed s'/ (.*)//'")
end repeat
end tell
The code posted by #adayzone will work, but there is no need to use sed for this – plain AppleScript will do, using offset:
set fullString to "Invoice 10.1 (2012) (Digital) (4-Attachments).pdf"
set trimmedString to text 1 thru ((offset of "(" in fullString) - 1) of fullString
-- trim trailing spaces
repeat while trimmedString ends with " "
set trimmedString to text 1 thru -2 of trimmedString
end repeat
this returns “Invoice 10.1". To split the file name into the name and extension, and re-add the extension, you can use System Events’ Disk-File-Folder suite, which will provide the handy name extension property you can store and re-add after trimming the name.
Assuming you use some Automator action to get the files to be processed, the full processing workflow would be to add an AppleScript action after the file selection part with the following code:
repeat with theFile in (input as list)
tell application "System Events"
set theFileAsDiskItem to disk item ((theFile as alias) as text)
set theFileExtension to name extension of theFileAsDiskItem
set fullString to name of theFileAsDiskItem
-- <insert code shown above here>
set name of theFileAsDiskItem to trimmedString & "." & theFileExtension
end tell
end repeat
If you want your Automator workflow to process the files any further, you will also have to create a list of aliases to the renamed files and return that from the AppleScript action (instead of input, which, of course, is not valid anymore).

applescript get rid of full path

I've got a choose file in my AppleScript. When I run the script and choose a file, the output is always the full file path with the file extension on the end. For example:
Macintosh HD:Developer:About Xcode.pdf
is what I don't want. I only want:
About Xcode
The below answer by Kassym Dorsel doesn't work when there is more than one . in it.
The below answer by Lri doesn't work with set x to choose file:
error "Can’t make quoted form of alias \"Macintosh HD:Applications:Firefox.app:\" into type Unicode text." number -1700 from quoted form of alias "Macintosh HD:Applications:Firefox.app:" to Unicode text
You can use the Finder to manipulate the names of Finder items:
choose file with prompt "Pick one"
set filepath to result
tell application "Finder" to set {dispName, nameExt, isHidden} to ¬
the {displayed name, name extension, extension hidden} of the filepath
if isHidden or nameExt is equal to "" then
dispName
else
(characters 1 through (-2 - (count of nameExt)) of dispName) as text
end if
set baseName to result
This will work :
set a to "Macintosh HD:Developer:About.Xcode.pdf"
set text item delimiters to ":"
set temp to last text item of a
set text item delimiters to "."
set temp to text items 1 thru -2 of temp as text
Gives => About.Xcode

Resources