AppleScript -- Checking to see if a file exists does not work - applescript

For some reason, when I check to see if a file exists, it always returns as true:
display dialog (exists (homePath & "Desktop/11-14.csv" as POSIX file as string))
That returns as true, no matter if there is a csv named that on my Desktop or not. I want to make an if function that works through file existence, but because it's always returning as true, it's screwing up my if function. What can I do to fix this?

Some explanation: The reason why it always returns true is that the file class exists rather than the file on your drive. It's the same as saying exists "Hello World!" which always returns true because the string "Hello World!" does indeed exists. By default the exists command just checks is the given value is missing value or not. When it is missing value it returns false, otherwise it will return true. However there are applications that overwrites the standard exists command like System Events and Finder for instance. So to use the exists command on a file and want to check if the file exists you should wrap your code in an tell application "System Events" or "Finder" block like in adayzdone example code.
There are more ways to skin this cat.
set theFile to "/Users/wrong user name/Desktop"
--using system events
tell application "System Events" to set fileExists to exists disk item (my POSIX file theFile as string)
--using finder
tell application "Finder" to set fileExists to exists my POSIX file theFile
--using alias coercion with try catch
try
POSIX file theFile as alias
set fileExists to true
on error
set fileExists to false
end try
--using a do shell script
set fileExists to (do shell script "[ -e " & quoted form of theFile & " ] && echo true || echo false") as boolean
--do the actual existence check yourself
--it's a bit cumbersome but gives you an idea how an file check actually works
set AppleScript's text item delimiters to "/"
set pathComponents to text items 2 thru -1 of theFile
set AppleScript's text item delimiters to ""
set currentPath to "/"
set fileExists to true
repeat with component in pathComponents
if component is not in every paragraph of (do shell script "ls " & quoted form of currentPath) then
set fileExists to false
exit repeat
end if
set currentPath to currentPath & component & "/"
end repeat
return fileExists

Try:
set xxx to (path to desktop as text) & "11-14.csv"
tell application "System Events" to exists file xxx

Related

How do I get the properties or the info of a file using AppleScript?

I need to write the properties or at least the info of a file I have only the name of (here: "text2.txt") to a textfile.
I tried various ways but each time I just get the properties of the Desktop folder but not the file.
What am I doing wrong here?
try
tell application "Finder"
set this_folder to path of (folder of the front Finder window) as alias
end tell
on error
-- no open folder windows
set this_folder to path to desktop folder as alias
set is_desktop to true
end try
tell application "System Events"
set file_list to the name of every file of this_folder
end tell
tell application "Finder"
set theFile to path to desktop folder
set myList to {}
repeat with n from 1 to count of file_list
set currentFile to item n of file_list
set the_filePath to this_folder
set the_filename to currentFile
if currentFile contains "text2.txt" then
set {creation date:creaDate, modification date:modDate, name:fName, displayed name:dName, name extension:nExt, description:descript, URL:fPath} to properties of the_filePath
set theText to creaDate & "#" & modDate & "#" & fName & "#" & dName & "#" & nExt & "#" & descript & "#" & fPath
do shell script "echo " & theText & ">> $HOME/Desktop/FileProperties.txt"
end if
end repeat
end tell
I think you mostly have it right already.
Finder windows have a 'target', which is the folder that the window looks at. You can get and set the target normally. Everything below the try statement is unchanged.
try
tell application "Finder" to set this_folder to target of front window as alias
on error
set this_folder to (path to desktop) as alias
set is_desktop to true
end try
As alternatives, the script could use TextEdit or its own 'write' command to create the text document. If you're curious, let me know and I'll add those options.
Okay… here is a script you can try that should handle the writing within applescript. I've made a few other tweaks, all of which are commented (which unfortunately, make the script appear longer than it really is).
Applescript has a built-in 'File Read/Write suite' which you can read about each command in the Language Guide here, but in a nutshell, you use these commands to write to a new file, replace or append text to an existing file.
p.s. I changed some of your variable names
-- Make front window specifier a global var. Unnecessary if you integrate System Events block into Finder block (see below)
global fw
tell application "Finder"
try
set targFol to target of front window as alias
set fw to front window
on error
set targFol to (path to desktop) as alias
set fw to make Finder window to targFol
end try
end tell
The system events block below could also be handled by the Finder. If the folders you're rooting through don't typically have thousands of files in them (or if the alternative line is sufficient), you should consider doing so, as the primary advantage of using System Events is performance with high file counts. I don't think any changes would be required beyond removing the appropriate 'tell/end' statements.
tell application "System Events"
-- Some filtering options as an alternative to the repeat loop
set txFiles1 to files of targFol whose kind is "Plain Text Document"
set txFiles2 to files of targFol whose kind is "Plain Text Document" and name is "text2.txt"
set txFile to item 1 of txFiles2
-- Alternatively, you can just use the file itself, without any of the rigmarole.
set txFile to file "text2.txt" of targFol
end tell
tell application "Finder"
set {creation date:creaDate, modification date:modDate, name:fName, displayed name:dName, name extension:nExt, description:descript, URL:fPath} to properties of targFol
set newText to creaDate & "#" & modDate & "#" & fName & "#" & dName & "#" & nExt & "#" & descript & "#" & fPath as text
end tell
-- Write the properties as text to a text file -- requires the 'class furl' bit to work
set tf to (path to desktop as text) & "FileProperties.txt" as «class furl»
-- Alternatively, you could create the text file in the target folder
-- set tf to (targFol as text) & "FileProperties.txt" as «class furl»
close access (open for access tf)
write newText to tf as text
-- And some obvious things you can do with your new text file
tell application "TextEdit" to open tf
tell application "Finder" to select tf
set rtext to read tf
I made a few adjustments to your code. Maybe something like this will help you out.
property theFile : "text2.txt"
tell application "Finder"
try
-- Gets The Name Of The Front Finder Window If There Is One Opened
set containerName to name of front Finder window as POSIX file as text
-- Checks If The File "text2.txt" Exists In That Folder
-- fileExists Will Be Set To True Or False Depending On The Results
set fileExists to (containerName & theFile) as alias exists
on error errMsg number errNum
-- If Either Of The Previous Commands Throws An Error
-- This Will Give You An Option To Choose A Folder Where You Think
-- The File "text2.txt" Is Located
activate
set containerName to my (choose folder with prompt "Choose A Folder") as text
end try
try
-- Checks If The File "text2.txt" Exists In The New Chosen Folder
set fileExists to (containerName & theFile) as alias exists
on error errMsg number errNum
-- If "text2.txt" Does Not Exist In This Folder Either, Script Stops Here
return
end try
delay 0.1
-- If fileExists Is Set To True From Previous Commands
if fileExists then
set fullFilePath to (containerName & theFile) as alias
set {creation date:creaDate, modification date:modDate, name:fName, displayed name:dName, name extension:nExt, description:descript, URL:fPath} to properties of fullFilePath
set theText to creaDate & "#" & modDate & "#" & fName & "#" & ¬
dName & "#" & nExt & "#" & descript & "#" & fPath
tell current application to (do shell script "echo " & theText & ¬
">> $HOME/Desktop/FileProperties.txt")
end if
end tell

Play sound with AppleScript using afplay and relative file path

I'm trying to create an AppleScript that uses afplay (as suggested here) to play a random sound file that's located in a directory within the same directory as the script.
folder
-- applescript.scpt
-- sounds
----- sound-x.aiff
I found this comment regarding relative paths to be potentially useful:
(POSIX path of (path to me))
However, I keep receiving errors when I try mashing it up with this approach for randomness...
set theNumber to 3
set theFiles to {}
repeat
set file_path to quoted form of (POSIX path of (path to me))
tell application "Finder" to set aFile to (some file of file_path & "/sounds_dir") as text
if aFile is not in theFiles then
set end of theFiles to aFile
tell application "Finder" to open file aFile
do shell script ("afplay " & file_path & " > /dev/null 2>&1 &")
end if
if (count of theFiles) is equal to theNumber then exit repeat
end repeat
In a script, path to me returns the path to the script file but we need its parent path to add a sub path.
To compose the correct path, we can use the subroutine composeFilePath(fileName).
The main action is in the repeat loop. I also added a delay so it's easier to test. Save the script before using since path to me will return a wrong path when its unsaved.
set LOOPS to 3
set soundFolderName to "sounds_dir"
# ---------------------
# SETUP
# ---------------------
set soundFolderFullPath to my composeFilePath(soundFolderName)
tell application "Finder"
if folder soundFolderFullPath exists then
set soundFolder to (folder soundFolderFullPath)
else
set soundFolder to ""
# Customize action when folder does not exist
beep
log "*** Error: folder " & quoted form of soundFolderFullPath & " missing!"
return
end if
if (count files in soundFolder) is 0 then
# Customize action when folder has no items in it
beep
log "*** Error: No items in " & quoted form of soundFolderFullPath & " !"
return
end if
end tell
# -------------------------------------------
# We have "soundFolder" and it has items in it
# -------------------------------------------
repeat LOOPS times
# PLAY RANDOM FILE
# As ONE LINER:
## do shell script "/usr/bin/afplay " & quoted form of (POSIX path of ((some file of soundFolder) as text)) & " > /dev/null 2>&1 &"
# Step By Step
set aRandomFile to some file of soundFolder
set aRandomFile to POSIX path of (aRandomFile as text)
set shellScript to "/usr/bin/afplay " & quoted form of aRandomFile & " > /dev/null 2>&1 &"
do shell script shellScript
delay 1
end repeat
on composeFilePath(fileName)
if fileName is "" then return ""
set pathToMe to path to me -- this is the full path to this script
-- get the folder this script is in:
set thisScriptsFolder to ""
tell application "Finder"
try
set thisScriptsFolder to (get container of pathToMe) as text
end try
end tell
if thisScriptsFolder is "" then
return ""
end if
return thisScriptsFolder & fileName -- full path
end composeFilePath
You have your paths all messed up. Applescript doesn't use "posix paths" so you can't pass that type of path to applications such as the Finder. Shell scripts do use posix paths and you have to quote them.
In addition for applescript, whenever your path is in string format you must put the word "file" or "folder" in front of the path before you use it so that applescript can understand it's an object to be acted upon otherwise applescript just treats it like a string. Also string paths in applescript should be colon delimited (:) rather than slash delimited (/). Finally applescript paths start with the name of your hard drive such as "Macintosh HD".
You can see you must treat paths in applescript much differently than you do with the shell. Anyway, I didn't test this code but using those basic rules this should work. Good luck.
set theNumber to 3
set theFiles to {}
repeat
set file_path to (path to me) as text
set file_dir to file_path & ":sounds_dir:"
tell application "Finder" to set aFile to (some file of folder file_dir) as text
if aFile is not in theFiles then
set end of theFiles to aFile
tell application "Finder" to open file aFile
do shell script "afplay " & quoted form of POSIX path of aFile & " > /dev/null 2>&1 &"
end if
if (count of theFiles) is equal to theNumber then exit repeat
end repeat

OSX: How can check whether a file exists in current directory using applescript?

I want to make an automator app which creates an empty file in current directory.
I did some google search and found:
http://hints.macworld.com/article.php?story=20050219134457298 and http://hints.macworld.com/article.php?story=20100509134904820
However, I want to do something more powerful.
If the specified file already exists, I want to show a warning instead of overwriting the original file, which is what one of the above link does. (The other one creates a text file using textEdit. I do not want to create text file. I want an empty file like what linux/unix does)
I already figured out how to do most of the part, but
How can check whether a file exists in current directory using applescript??
How can I concatenate two variable in applescript?
Checking if a file exists (assuming thefullpath is already set as in the referenced question):
tell application "Finder"
if exists POSIX file thefullpath then
--do something here like
display alert "Warning: the file already exists"
end if
end tell
Not sure what you mean by the second part but if you want to concatenate strings stored in var1 and var2 you could simply do
var1 & var2
Something I have been using a lot of late for this sort of thing is the command /bin/test
The test test for the existence of in this case a file
if (do shell script "/bin/test -e " & quoted form of (POSIX path of theFile) & " ; echo $?") is "1" then
-- 1 is false
--do something
end if
The -e option:
-e file True if file exists (regardless of type).
The are tons of other test options shown in the /bin/test man page
The following code, adapted from your second link, is usually right, but it doesn't always work. The current directory is better specified as the directory of the document that is being opened which is most likely from the Finder's front window, but not necessarily. I like to write code that will work no matter what.
on run {input, parameters}
tell application "Finder"
set currentPath to insertion location as text
set x to POSIX path of currentPath
display dialog "currentPath: " & (x as text)
end tell
return x
end run
I wrote a whole "Run AppleScript" action to put things into context:
on run {input, parameters}
# count the number of files
set numFiles to 0
repeat with f in input
# warn the user that folders are not processed in this app
tell application "Finder"
if (kind of f is "Folder") then
display dialog "The item: " & (f as text) & " is a folder. Only files are allowed. Do you want to continue processing files or do you want to cancel?"
else
set numFiles to numFiles + 1
end if
end tell
end repeat
# require that at least one file is being opened
if numFiles < 1 then
display alert "Error: the application Test1.app cannot be run because it requires at least one file as input"
error number -128
end if
# get the current directory from the first file
set theFirstFile to (item 1 of input)
tell application "System Events" to set theFolder to (container of theFirstFile)
# ask the user for a file name
set thefilename to text returned of (display dialog "Create file named:" default answer "filename")
# create the file
tell application "System Events" to set thefullpath to (POSIX path of theFolder) & "/" & thefilename
set theCommand to "touch \"" & thefullpath & "\""
do shell script theCommand
# return the input as the output
return input
end run
The "touch" command is OK. If the file doesn't exist, it is created and if it does exist, only the modification date is changed (which isn't too bad) but it doesn't overwrite the file. If your file is being overwritten, it's not the touch command that is doing it.
I changed the default file name to remove the extension ".txt" This extension may default to being opened by TextEdit.app, but you can change this in the Finder by choosing "Get Info" for a file and changing the "Open With" property. You can change which application opens the file with that extension or you can change them all. For example, all of my ".txt" files are opened with BBEdit.app
Will you vote my answer up?
Another option that doesn't require Finder or System Events is to try to coerce a POSIX file or file object to an alias:
try
POSIX file "/tmp/test" as alias
true
on error
false
end try

Applescript to check if files exist

I want to check if any of particular files (dictionaries) exist in "/Library/Dictionaries/". Here is my Applescript code lines:
tell application "Finder"
try
set theFolder to ("/Library/Dictionaries/")
set fileNames to {"dict1.dictionary", "dict2.dictionary", "dict3.dictionary", "dict_n.dictionary"}
on error
set fileNames to false
end try
if fileNames is not false then
try
display dialog "You have already got the dictionary."
end try
end if
end tell
Weirdly, the message You have already got the dictionary. is always shown albeit no listed files exist.
My purpose is to check if any of the listed files exits, and if one or more of them exits then the message is to be displayed.
In fact, this script will be run as a Unix bash script via /usr/bin/osascript, so I will be very grateful if you can help with either Apple script or Bash script.
Try
set theFolder to (path to library folder as text) & "Dictionaries:"
set fileNames to {"Apple Dictionary.dictionary", "dict2.dictionary", "dict3.dictionary", "dict_n.dictionary"}
set dict to {}
repeat with aFile in fileNames
tell application "Finder"
if exists file (theFolder & aFile as text) then set end of dict to aFile & return
end tell
end repeat
if dict ≠ {} then display dialog "You have the following dictionaries installed:" & return & dict
Another method is to try to coerce a file object to an alias:
set p to (system attribute "HOME") & "/Desktop/test.txt"
try
POSIX file p as alias
true
on error
false
end try
Note that this results in an error when as alias is evaluated:
"/non-existing/path"
tell application "Finder" to exists POSIX file result as alias
This doesn't result in an error:
POSIX file "/non-existing/path"
tell application "Finder" to exists result

How find the file name of an executing AppleScript

How do I find the name of an executing AppleScript?
REASON: I want to create a script that changes its behavior based on its filename. Something like:
if myname is "Joe" then ACTION1
else if myname is "Frank" then ACTION2
else ACTION3
The normal way to get the name is by using "name of me". However applescripts are run by applescript runner so when you use that on a script you get "Applescript Runner" as the name. If you compile your script as an application then "name of me" will work. The only way to get the script name is by getting its path and extracting the name. Something like this would thus work for scripts...
getMyName()
tell me to display dialog result
on getMyName()
set myPath to path to me as text
if myPath ends with ":" then
set n to -2
else
set n to -1
end if
set AppleScript's text item delimiters to ":"
set myName to text item n of myPath
if (myName contains ".") then
set AppleScript's text item delimiters to "."
set myName to text 1 thru text item -2 of myName
end if
set AppleScript's text item delimiters to ""
return myName
end getMyName
Here's a method that works for all of the following:
*.scpt files (compiled AppleScript files; run in AppleScript Editor or with osascript)
*.applescript files (uncompiled AppleScript files; run in AppleScript Editor or with osascript)
command-line scripts that directly contain AppleScript (marked as executable and starting with #!/usr/bin/env osascript):
*.app files created with AppleScript Editor
*.app files created with Automator that contain AppleScript actions
Note: By contrast, it does not work for the following:
OS X services created with Automator that contain AppleScript actions (special *.workflow files) - always reports 'WorkflowServiceRunner[.xpc]'
general-purpose *.workflow files created with Automator that contain ApplesScript actions and that are run with automator - always reports 'Automator Runner[.app]'
Get the name of the running script, including filename extension (.scpt, .app, or .applescript, as the case may be):
tell application "System Events" to set myname to get name of (path to me)
If you want to remove the filename extension with a single command, use the following, do shell script-based approach:
tell application "System Events" to set myname to do shell script "rawName=" & quoted form of (get name of (path to me)) & "; printf '%s' \"${rawName%.*}\""
Here's an all-AppleScript alternative that is more verbose (yet concise by AppleScript standards):
tell application "System Events"
set myname to name of (path to me)
set extension to name extension of (path to me)
end tell
if length of extension > 0 then
# Make sure that `text item delimiters` has its default value here.
set myname to items 1 through -(2 + (length of extension)) of myname as text
end if
Finally, here's a variation: a subroutine that you can call with set myname to getMyName():
on getMyName()
local myName, tidSaved
tell application "System Events"
set myAlias to path to me -- alias to the file/bundle of the running script
set myName to name of myAlias -- filename with extension, if any.
if name extension of myAlias is not "" then -- strip away extension
set {tidSaved, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {""}}
set myName to items 1 through -(2 + (length of (get name extension of myAlias))) of myName as text
set AppleScript's text item delimiters to tidSaved
end if
end tell
return myName
end getMyName
An easier way to find out the base part of the path is using name of:
tell application "Finder"
set p to path to me
set nam to name of file p as text
end tell
Maybe this:
set appname to name of current application

Resources