basename

I often use the Unix command basename, which returns the filename portion of the specified path. Here’s an AppleScript version that uses text item delimiters:

on basename(thePath) -- Requires POSIX path
	set ASTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "/"
	set thePath to text item -2 of thePath
	set AppleScript's text item delimiters to ASTID
	return thePath
end basename

-- Test it: basename(POSIX path of (choose folder))

Model: Mac mini
AppleScript: 1.10
Browser: Safari 412
Operating System: Mac OS X (10.4)

That’s a nice, fast way to do it. With a slight modification, it can handle both file and folder names:

on basename(thePath) -- Requires POSIX path
	if thePath ends with "/" then
		set nameIndex to -2
	else
		set nameIndex to -1
	end if
	set ASTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "/"
	set thePath to text item nameIndex of thePath
	set AppleScript's text item delimiters to ASTID
	return thePath
end basename

-- basename(POSIX path of (choose file))
set orig_filename to (call method "lastPathComponent" of aFilepath)
set base_path to (call method "stringByDeletingLastPathComponent" of aFilepath)

probably only works for posix paths…

That doesn’t compile. Does it require a particular OSAX or application?

No. Its in my Applescript Studio application. It works fine there. Maybe just not in regular applescript? I dun’t know.

AppleScript Studio apps support this (If you have one, look under Application Suite). I was aware of that method, but I didn’t know how to use call method with plain AppleScript. I have a background AS Studio app I can use to call methods, but it’s not a very portable way of doing things.

If you do have an AS Studio app, try something like this:

get POSIX path of (choose folder)
tell application "Your Studio App" to call method "lastPathComponent" of result

Nigel, I noticed that later. It slipped by because I only use basename on folders. Thanks for the correction.

bumping an old post but I think it’s correct here.

basename as it works in the shell; tried to simulate as much as much code as in the basename command line utility. Still it is about 50 times faster as in a single do shell script command.

baseName("/") --result : /
baseName("/a") --result : a
baseName("/a/b") --result : b
baseName("/a/b/") --result : b
baseName("/a/b//") --result : b
baseName("/a/b/c") --result : c
baseName("/a/b/c/") --result : c
baseName("/a/b//c") --result : c
baseName("/a//b/c") --result : c

on baseName(__n)
	script s
		property AoB : missing value
	end script
	if __n's length < 2 then return __n
	set s's AoB to id of __n
	repeat until last item of s's AoB is not 47
		set s's AoB to items 1 thru -2 of s's AoB
	end repeat
	set b to {}
	repeat with x from 1 to count s's AoB
		if item x of s's AoB = 47 then
			set b to {}
		else
			set end of b to item x of s's AoB
		end if
	end repeat
	return string id b
end baseName