user3577225
user3577225

Reputation:

Expand a POSIX path with prefix "~" (using AppleScript)

StandardAdditions has the path to command and we can use it to get known locations.

For example, path to home folder returns a file reference to the user folder and if we want the posix path, we can do POSIX path of ((path to home folder) as text).


In Terminal.app we can use the tilde character (~) to represent the home folder.

How can we do this tilde expanding in AppleScript?

Upvotes: 1

Views: 1138

Answers (4)

Mr. Science
Mr. Science

Reputation: 39

Here's a handy applescript one-liner that resolves any posix path beginning with a tilde (Sample path included.) Afterwards you'll find sample conversions to other path formats.

set psxPTH to "~/Library/Scripts/"
if character 1 of psxPTH contains "~" then set psxPTH to POSIX path of (path to home folder) & text (2 + (offset of "~" in psxPTH)) thru -1 of psxPTH
------>"/Users/Mr.Science/Library/Scripts/"

--other steps after the posix is resolved...

set hfsPTH to (POSIX file psxPTH) as text
------> "Macintosh_Harddrive:Users:Mr.Science:Library:Scripts:"

set alsPTH to alias hfsPTH
------> alias "Macintosh_Harddrive:Users:Mr.Science:Library:Scripts:"

tell application "Finder" to set vrbspth to item alsPTH
------> folder "Scripts" of folder "Library" of folder "Mr.Science" of folder "Users" of startup disk of application "Finder"

Upvotes: 0

user3577225
user3577225

Reputation:

More coming soon


How to expand a posix path that can start with the tilde character ~?
(~ represents the home folder)

Here the script+demo:

#

demo()

# ------------------------------------------------------------
#
# expandTildeInPath ( localPath, outputStyle )
#
# ------------------------------------------------------------
# When outputStyle is true  : returns posix path
# When outputStyle is false : returns alias
# ------------------------------------------------------------
# localPath format:
# ------------------------------------------------------------
# • posix path - a posix path (can start with a  tilde "~")
# • alias
# • path (text) with ":"  => (alias as text) produces this
# ------------------------------------------------------------
on expandTildeInPath(localPath, outputStyle)

    # ------------------------------------------------------------
    # If necessary, convert localPath to text and posix path:
    # ------------------------------------------------------------

    if (class of localPath is alias) then
        # alias
        set localPath to POSIX path of (localPath as text)
    else if (class of localPath is text) and (localPath contains ":") then
        # (fileAlias as text) produces such a colon delimited path:
        set localPath to POSIX path of localPath
    end if

    set resultPath to localPath

    # -------------------------------
    # If necessary, expand tilde:
    # -------------------------------

    if localPath starts with "~" then

        # input is like: "~", "~/" or something with a sub path, like "~/Movies"
        set homeFolder to POSIX path of ((path to home folder) as text)
        if (localPath = "~") or (localPath = "~/") then
            # no sub-path
            set resultPath to homeFolder
        else
            if not (localPath starts with "~/") then
                # this is not a valid path to expand but an item that starts with "~"
                return localPath
            end if
            # add sub-path
             set subPath to ((characters 3 thru -1) of aPath) as text
             set sDel to "/"
             if (subPath starts with sDel) then set sDel to ""
             set resultPath to homeFolder & sDel & subPath
        end if
    end if

    # -------------------------------
    # return posix path or alias:
    # -------------------------------

    if outputStyle then
        return (POSIX path of resultPath)
    else
        # the location must exist or "as alias" throws an error.
        try
            set a to (resultPath as POSIX file) as alias
            return a
        on error
            log "*** Error ***" & resultPath & " does not exist"
            return localPath
        end try
    end if

end expandTildeInPath





# ------------------------------------------------------------
# Sub Routines for Demo
# ------------------------------------------------------------

on demo()

    set asAlias to false
    set asPosixPath to true

    # Does not expand since its a name that starts with "~":
    logDemo("~testFile", asAlias)

    # FolderThatDoesNotExist:
    logDemo("~/FolderThatDoesNotExist", asAlias) # this throws an error (in the log) and returns the unchanged input
    logDemo("~/FolderThatDoesNotExist", asPosixPath) # returns expanded posix path (existing or not)

    # Main Usage 
    logDemo("~", asPosixPath)
    logDemo("~", asAlias)
    logDemo("~/", asPosixPath)
    logDemo("~/", asAlias)

    logDemo("~/Documents/", asPosixPath)
    logDemo("~/Documents/", asAlias)

    # convert a posix path like "/Applications" to alias
    logDemo("/Applications", asAlias)

    set input to "~/Music/iTunes/iTunes Library.xml"

    set filePosixPath to expandTildeInPath(input, asPosixPath)
    set fileAlias to expandTildeInPath(input, asAlias)

    log quoted form of input
    log quoted form of filePosixPath
    log fileAlias
    logLine()

    # Using alias with Finder is so easy:
    tell application "Finder"
        if exists fileAlias then
            # activate
            # reveal fileAlias
        end if
    end tell


    # --------------------------
    # Other input formats:
    # --------------------------
    # This is also possible (not intended but it works):

    # we can use text paths (containing ":"):
    logDemo((path to documents folder as text), false)

    # we can use aliases:
    # (makes no sense at all when we return an alias but this is to show that it works)
    logDemo((path to documents folder), false)

    # Same as above but output as posix path:
    logDemo((path to documents folder as text), true)
    logDemo((path to documents folder), true)

end demo

on logLine()
    log "---------------------------------------------"
end logLine

on logDemo(inputPath, outputStyle)
    set a to expandTildeInPath(inputPath, outputStyle)
    if outputStyle then
        log "input: " & inputPath & " output: " & quoted form of a
    else
        log "input: " & inputPath & "      output (next line): "
        log a # don't mix with text or it does not show the "alias" in the log
    end if
    logLine()
end logDemo

# ------------------------------------------------------------

Here a little addition to show the system attributes:

set saList to system attribute
repeat with sa in saList
    log quoted form of sa & " = " & quoted form of (system attribute sa)
end repeat

Upvotes: 0

ShooTerKo
ShooTerKo

Reputation: 2282

Started with OS X 10.10 you can easily access Cocoa classes and their functions and properties:

use framework "Foundation"

expandTilde("~/Desktop")

on expandTilde(givenPath)
    -- create a temporary Obj-C/Cocoa NSString object with the givenPath
    set tempCocoaString to current application's NSString's stringWithString:givenPath
    -- call the object's stringByExpandingTildeInPath method
    -- to create a new path with expanded tilde
    return (tempCocoaString's stringByExpandingTildeInPath) as string
end expandTilde 

In 10.9 you have to define such handlers in Scripting Libraries, that's less nice than it sounds. But in 10.10 this works out of the box!

Upvotes: 5

Frank C.
Frank C.

Reputation: 8088

Zero

There is more than one way to skin that cat. As you pointed out, or with the simple:

system attribute "HOME"

And then concatenate on the remaining path.

Upvotes: 1

Related Questions