get filename

I am looking to find a script that would get the file name and extension. And use the file name as a veritable

Moved the topic to the appropriate forum :wink:


set posixPath to POSIX path of (((path to desktop folder) as text) & "testfile.txt.zip")
set {fname, fextension} to paragraphs of (do shell script "a=$(basename " & quoted form of posixPath & ");echo ${a%.*};echo ${a##*.}")

Hello!

This take, splits the filename into {path, name, ext } :slight_smile:

This is a compulsive thing as I saw the technique in This very fine article!


set hfsfile to (choose file)

splitAFile for hfsfile
log result
to splitAFile for aHfsFile
	local basename, pth, file_name, theExt, fn_len, ext_len
	
	tell application "Finder"
		set {{container:pth, name:file_name, name extension:theExt}, {name:{length:fn_len}, name extension:{length:ext_len}}} to {aHfsFile, aHfsFile}
	end tell
	
	set basename to text 1 thru (fn_len - (ext_len + 1)) of file_name
	return {pth as alias as text, basename, theExt}
end splitAFile

You should seek treatment :wink: Six Apple events for two bits of information, and it still has to parse the name… Wow…

:wink:

Well, two events for two bits of info isn’t that expensive, the thing here, was really to extract properties with nested records. :smiley:


set hfsfile to (choose file)

splitAFile for hfsfile
log result
to splitAFile for aHfsFile
	local basename, pth, file_name, theExt, fn_len, ext_len
	
	tell application "Finder"
		set {name:file_name, name extension:theExt} to aHfsFile
	end tell
	set {fn_len, ext_len} to {length of file_name, length of theExt}
	set basename to text 1 thru (fn_len - (ext_len + 1)) of file_name
	return {basename, theExt}
end splitAFile

It’s a lot better than six :slight_smile:

I know, and the usage, wasn’t much practical as length is a general property, in that it doesn’t require you to adress an app.

But other nested properties, will be no less efficently extracted this way, than by conventional means, I have no idea if it will be faster, or if you only obfuscate the code though, but it is at least more efficienct with regards to the number of lines. One have to be aware of, and take height for the need of explicitily using get for evaluation though, as Kai Edwards states in the article.

This is a good example from the article referenced above, on how to extract nested properties, by nested records. :slight_smile:


tell application "Finder" to tell Finder window 1
   if not (exists) then return display alert "No Finder windows open" message "Please open any folder and try again."
   set {name:n, sidebar width:b, statusbar visible:v, list view options:{icon size:i, calculates folder sizes:c, uses relative dates:r, sort column:{name:s, width:w, sort direction:d}}} to it
   display alert "Example of nested Finder window properties:" message "FINDER WINDOW:
   name: " & n & "
   sidebar width: " & b & "
   statusbar visible: " & v & "
   
   LIST VIEW OPTIONS:
       icon size: " & i & "
       calculates folder sizes: " & c & "
       uses relative dates: " & r & "
   
       SORT COLUMN:
           name: " & s & "
           width: " & w & "
           sort direction: " & d
end tell

And it’s very efficient in terms of just how many events can be launched from one line of code – the event log shows this time you sent 13…

:smiley:

Can you get the same amount of info without sending 13 events? I think, (but I may be wrong, but I think since those are properties of the Finder Window, which is a property of the Finder, that I have to send that amount of events to get that amount of info, anyway! :slight_smile:

Back to the topic, I’m using this for years


set theFile to (choose file)
set {name:fileName, name extension:fileExtension} to info for theFile
if fileExtension is missing value then set fileExtension to ""
set fileName to text 1 thru ((count fileName) - (count fileExtension) - 1) of fileName

This takes four:

tell application "Finder"
	if exists Finder window 1 then
		set {name:n, sidebar width:b, statusbar visible:v, list view options:lvo} to properties of Finder window 1
		set {icon size:i, calculates folder sizes:c, uses relative dates:r, sort column:sc} to properties of lvo
		set {name:s, width:w, sort direction:d} to properties of sc
	end if
end tell 

But the dictionary entry for “info for” says, “This command is deprecated”.

I know, it’s deprecated since Leopard (or even Tiger) but it still works in Mountain Lion.

Maybe this is a wrong information.

in CoreServices’ File Manager there are a lot of functions deprecated in Tiger and later but for example
FSGetCatalogInfo() is not deprecated

I see, for the attributes directly dependent of another, it doesn’t take an event, as they are “delivered” with the “governing” property. :slight_smile:

And System Events is of course not faster? :slight_smile:

But I think FSGetCatalogInfo() is deprecated in 10.8.

As you say, there are several commands that have been deprecated for many versions yet still work. But the deprecation list for APIs in 10.8 looks a little more serious.

I thought I’d have a go at a “sed” solution. It ain’t pretty, but it works, even where there’s no extension. :slight_smile:

set f to (choose file)
set {fname, fextension} to paragraphs of (do shell script "echo " & quoted form of (f as text) & " | sed -E 's/.+:(([^:]+)[.]([^:.]*)|([^:.]+)):?$/\\2\\4\\" & linefeed & "\\3/'")

Edit: A dedicated capturing group for extensions which didn’t exist is now cut, since the one for those that do covers both possibilities! If “sed” supported non-capturing groups (which it doesn’t appear to do), the unneeded capture of the entire alternation group could be avoided too.

Can be solved :slight_smile:

set posixPath to POSIX path of (((path to desktop folder) as text) & "test file.txt.zip")
set {fullname, fname, fextension} to paragraphs of (do shell script "b=$(basename " & quoted form of posixPath & ");echo $b; echo ${b%.*};echo ${b##*.}")
if fullname is fname then return {fullname, missing value}
return {fname, fextension}

Vanilla that delivers missing value for dirname, filename and suffix.
Probably a tad slower, but not that slow!


set posixPath to POSIX path of (((path to desktop folder) as text) & "test file.txt.zip")
set res to split for posixPath
”>{"/Users/McUsr/Desktop/", "test file.txt", "zip"}
set posixPath to POSIX path of (((path to desktop folder) as text) & "test file")
”>{"/Users/McUsr/Desktop/", "test file", missing value}
set posixPath to "~/usr/"
set res to split for posixPath
”>{"~/usr/", missing value, missing value}

set posixPath to "/usr"
set res to split for posixPath
”>{ "/", "usr", 	missing value }
to split for pxpath
	local ppl, sl, s, tids, f
	set ppl to length of pxpath
	set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
	
	set s to item -1 of text items of pxpath
	set sl to length of s
	if sl = ppl then
		set s to missing value
		set pxpath to text items 1 thru -1 of pxpath as text
	else
		set pxpath to text items 1 thru -2 of pxpath as text
	end if
	set AppleScript's text item delimiters to "/"
	
	set f to item -1 of text items of pxpath
	if f = "" then set f to missing value
	try
		set pxpath to (items 1 thru -2 of text items of pxpath)
		set pxpath to (pxpath as text) & "/"
	on error
		set pxpath to missing value
	end try
	set AppleScript's text item delimiters to tids
	return {pxpath, f, s}
end split

You have a few problems there. You’re not allowing for file packages, and you’re not allowing for / as a character. It seems to me that going POSIX for this is adding unnecessary complication. I also don’t understand what “text item -1 of text items” is for.

This seems pretty simple to me:

set x to choose file
set theExt to ""
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {":"}
set theName to text item -1 of (x as text)
if theName = "" then set theName to text item -2 of (x as text)
set AppleScript's text item delimiters to {"."}
if (count of text items of theName) > 1 then
	set theExt to text item -1 of theName
	set theName to text 1 thru text item -2 of theName
end if
set AppleScript's text item delimiters to saveTID
return {theName, theExt}