Noobie having difficulty with something simple

I hate to bring really simple stuff to a forum but so far I have watched dozens of YouTube videos and read many more posts and cannot do something really simple.
BTW the advice on what books for starters is looking pretty old… most of the advice predates 2008 and some of the books are out of print.
OK here is the simple problem. Have the user select a file, answer a series of dialogs which is concatenated into a string which I want to use to replace the file name. I have tackled this in pieces and now have a script which captures the string in a variable.
The part I cannot figure out is how to replace the portion of the name. Seems like it should be easy.
This little bit of code looked promising:

tell application "Finder"
   set the name of file "Monterey" to "Eden"
end tell 

but so far I have not figured out how to have the user select “Monterey”. Instead I have been fooling with a bit more complicated code.

tell application "Finder"
	set the name of file (get selection) to "newName"
	set fileToRename to (get selection) as text
	set oldDelims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {"."}
	set replacement_string to {"test with this"}
		set fileExtension to second text item of fileToRename
		set newName to replacement_string & {"."} & fileExtension
		set the name of fileToRename to newName --> rename the file
		set AppleScript's text item delimiters to oldDelims
	on error
		set AppleScript's text item delimiters to oldDelims
	end try
end tell

I think the simple thing I am missing is how to turn a full path/file.ext into a string, change part of the string then turn the result backinto the full path/newName.ext.


try this,
selection in Finder return always a list, so to process one file you have to get the first list item

set replacement_string to "test with this"
tell application "Finder" to set sel to selection -- returns a list
if sel is {} then return -- if nothing is selected exit the script
set fileToRename to item 1 of sel -- get first item.
set {fileName, fileExtension} to separateNameExt(fileToRename) -- separate name and extension
tell application "Finder" to set name of fileToRename to replacement_string & fileExtension -- rename the file

-- handler to separate name and extension of a file 
on separateNameExt(theFile)
	tell application "Finder" to set {name:fileName, name extension:fileExtension} to theFile
	if fileExtension is missing value then return {fileName, ""}
	return {text 1 thru ((count fileName) - (count fileExtension) - 1) of fileName, "." & fileExtension}
end separateNameExt

Thank you Stefan! I learned more in 20 minutes from your post than I did in a day.

This script as you posted it always returned a file name without extension. I was able to figure out that

 return {text 1 thru ((count fileName) - (count fileExtension) - 1) of fileName, "." & fileExtension}

was causing the the fileExtension to never get appended, so made this modification:

return {text 1 thru ((count fileName) - 1) of fileName, "." & fileExtension}

Here are some of the things I learned from your code:

  1. Approaching this as a list gives greater flexibility for using the code later for renaming a batch of files. I see the reason for doing it this way. Just to learn, is there syntax for only returning one item? Is this what “get” is used for?
  2. Just by using set nameOfsomething to selection an array is returned?
  3. item is a special word which refers to individual values in an array? What class is this value, string?
    4)the handler which separates the name and ext is passed the item… this is where things get really interesting… It seems like what is happening is that two properties of what is passed, the file name and the file extention are assigned to theFile which makes theFile a hash and it is possible to check for a missing extension with “is missing value” and return only the fileName… not actually sure why this is done as this value is not used? So I modified that line to be:
if fileExtension is missing value then return {""}

and it worked just fine.

I went through all this, just in case someone might read it and recognize what would help me most in getting to grips with Applescript. I would like to have a reference/tutorial. But I guess that simply staring at code and experimenting with changes will eventually bring enlightenment?

The handler separateNameExt() returns always a list of two elements, filename and file extension, not a single string
The list is represented by the curly braces.
You can assign the return values directly with

set {fileName, fileExtension} to separateNameExt(someFile)

If the name extension is undefined, an empty string is returned

If you are learning AppleScript there are some things you should know when working with file extensions. First of all, there is no file extension, Mac OS X is built on top of the virtual file system named UNIX File System (UFS). UFS doesn’t support extensions like MS-DOS file system does, only allows one and long file name. That means that the file extension and file name are something that virtually shown by the Finder to the user using Mac OS X’s own file manager. That includes that the same script running on a different system could give you different results, which would not be possible if file extensions were actually part of the file system.

Rename any file so it has an extension name “1” (or another file extension that is not supported by the Finder). Well now it’s getting interested. When using Stefan’s code using the Finder it will tell you it has no extension. Getting properties of a file using System Events, which is Apple’s suggested successor to the deprecated info forcommand. As promised the file properties are pretty much like info for which mean that the file with the extension “1” is considered an valid extension by System Events. Aren’t the Finder and System Events using the same file manager and file system? No, like mentioned before there is no extension in the file system itself, The Finder and System Events seems to have their own implementation on determining the extension of a file. The Finder will look if it supports the extension while system events does not.

When a file has an extension “1” System Events will return the file extension “1”

separateNameExt(choose file)

on separateNameExt(theFile)
	tell application "System Events" to set {name:fileName, name extension:fileExtension} to theFile
	if fileExtension is in {missing value, ""} then return {fileName, ""}
	return {text 1 thru ((count fileName) - (count fileExtension) - 1) of fileName, fileExtension}
end separateNameExt

When a file has an extension “1” the Finder will return no extension

separateNameExt(choose folder)

on separateNameExt(theFile)
	tell application "Finder" to set {name:fileName, name extension:fileExtension} to theFile
	if fileExtension is in {missing value, ""}  then return {fileName, ""}
	return {text 1 thru ((count fileName) - (count fileExtension) - 1) of fileName, fileExtension}
end separateNameExt

The same results as system events but faster and plain AppleScript:

separateNameExt("noextension") -- result: {"noextension", missing value}
separateNameExt("standardextension.txt") -- result: {"standardextension", "txt"}
separateNameExt("") -- result: {"", "1"}

on separateNameExt(fileName)
	if fileName does not contain "." then return {fileName, missing value}
	set oldTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "."
	set fnm to text items 1 thru -2 of fileName as string
	set ext to text item -1 of fileName
	set AppleScript's text item delimiters to oldTIDs
	return {fnm, ext}
end separateNameExt

Another drawback, which is more of a general problem, is that the Finder doesn’t look if the file is actually the right type. When I change the extension in the Finder of a file into jpeg (which was txt) the Finder will handle the file as JPEG and becomes “corrupted”. Both System Events and Finder will consider the file to be JPEG. When you use UNIX’s method to determine a file type, which is not based by it’s extension but based on MAGIC numbers and contents, the file type remains a text file and won’t be considered a JPEG format. Keep this in mind when you ever consider to work with both worlds the file type in unix can be completely different from the file type in the Finder. Because unix file type is based on content and finder file type seems to be based solely on the extension.

Why am I saying all this? Well you may experience in the future different results from different ways of scripting using different file systems but also between different OS. I wanted to give you some head start. All these issues comes from the fact that HFS+ should not have been implemented in Mac OS X. Or at least the Finder shouldn’t use any HFS+ specific features but only UFS features. That is because everything goes through UFS and nothing is written directly to the HFS+ file system. So UFS is tweaked in a such a way that the actual data stored on an HFS+ file system is very ugly. Or as Linus Torvalds said “utter crap which makes it a scary file system”.

Hi DJ,

This is the info that I’ve been searching for regarding the other post about the .bak extension. I thought unix had something to do with it, but couldn’t find info on it. It was on my mind all night and morning. :slight_smile:

Edited: and btw, I’ve noticed that when I add the .bak extension a .txt file still opens in TextEdit.

Thanks a lot,

One thing I’ve noticed about.bak files is that when you double click on them, they open in TextEdit if they were originally .txt. I was thinking that apps might notice if the extension is bak then they would look for the next extension or something like that.

Once a file is opened with text edit (and saved) additional finder information is saved as metadata and binded to the file. Finder information, a typical HFS(+) feature, is commonly ignored by most software. Data as 4 byte creator code and 4 byte file type are typical classic Mac OS ways store file information inside the HFS Catalog files and folders. But since Snow Leopard the Finder (or better said launch services) ignores the creator code but still respects the file type code, which can be of type ‘TEXT’ which causes the file to open in text edit. When you change the file type code tot ‘OSAS’ it will probably have an AppleScript icon and opens in ScriptEditor no matter which extension the file name contains.

note 1: These codes are case sensitive
note 2: Even if an valid file type code is assigned and the file is opened properly, it’s no guarantee that the Finder wil accept the extension as valid unfortunately