【问题标题】:How to get the a file URL in OSX with AppleScript or a shell script?如何使用 AppleScript 或 shell 脚本在 OSX 中获取文件 URL?
【发布时间】:2015-05-04 11:48:55
【问题描述】:

我尝试拼凑一个 Keyboard Maestro 快捷方式,为我提供文件的 URL(就像路径查找器输出的那些)。

到目前为止,我使用以下 AppleScript 并将 空格 替换为 %20

tell application "Finder"
    set sel to the selection as text
    set the clipboard to POSIX path of sel
end tell

然后我只需附加file://localhost/

问题在于特殊字符,例如我的桌面上有以下文件夹:

我的输出:file://localhost//Users/patte/Desktop/#%20Old%20files

正确的输出应该转换散列:file://localhost/Users/patte/Desktop/%23%20Old%20files


AppleScript 或 Shell 脚本的解决方案会很棒,因为我能够将其合并。我也尝试过set the clipboard to URL of the first item of (get the selection),但这对我不起作用——也许我做错了。

另一种选择是对特殊字符进行编码的脚本 - 我也可以使用它,但我不确定要转换成什么 - 否则我会寻找它。

【问题讨论】:

    标签: macos shell url applescript finder


    【解决方案1】:

    这是一个简单的 AppleScript,它将遍历 Finder 选择并将文件 URL 放在剪贴板上,以返回分隔的字符串形式。它使用 mklement 的“2 行”代码,可与 Keyboard Maestro 一起使用:

    set theOutput to ""
    
    -- Obtain Finder selection and store it in variable "sel".
    tell application "Finder" to set sel to get selection as alias list
    
    repeat with x in sel
    
    -- Convert to alias, then determine its file URL and store that in variable "myFileUrl"
    tell application "System Events" to set myFileUrl to URL of x
    
    if theOutput = "" then
        set theOutput to myFileUrl
    else
        set theOutput to theOutput & return & myFileUrl
    end if
    
    end repeat
    
    set the clipboard to theOutput
    

    【讨论】:

    • 此解决方案与最新的 OS X 版本最兼容,也可能与即将推出的版本兼容。感谢提交。
    【解决方案2】:

    这几乎是从this answer 逐字提取的,即在将file://localhost 添加到字符串的开头之前,利用python 的urllib 适当地引用字符串

    on path2url(thepath)
        return do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of thepath
    end path2url
    
    tell application "Finder"
        set sel to the selection as text
        set the clipboard to "file://localhost" & my path2url(POSIX path of sel)
    end tell
    

    为了使 python 脚本在 python 2.x 和 python 3 之间兼容,我在 print 周围添加了括号。

    【讨论】:

    • 感谢@Petesh,它运行良好。也许有人应该提到默认的python版本应该设置为2.x(因为print在python 3中不会像这样工作)。
    • mac上默认的python是2.x。我将对此效果的答案发表评论
    • 非常感谢皮特什。工作出色。
    【解决方案3】:

    有一个更健壮和方便的解决方案(在 10.7.4 上测试 - 不知道何时可用):

    -- Obtain Finder selection and store it in variable "sel".
    set sel to selection of application "Finder"
    -- Convert to alias, then determine its file URL and store that in variable "myFileUrl"
    tell application "System Events" to set myFileUrl to URL of (sel as alias)
    

    注意:

    • 仅当 Finder 选择仅包含 1 个项目时,示例才有效。
    • tell application "System Events" 部分是必不可少的,因为只有 System Events 字典包含具有 URL 属性的别名类的类型
    • 为简洁起见,这两个语句可以合并为一个。

    现在,假设您要创建一个 OS X 服务,将 Finder 中当前选择的文件和/或文件夹的文件 URL 复制到剪贴板:

    • 运行 Automator,选择文件 > 新建,然后选择创建新服务。
    • 在“已选择的服务接收”下,选择“文件或文件夹”,对于“in”,选择“Finder.app”
    • 添加“运行 AppleScript”操作。
    • 粘贴以下 AppleScript 代码:
    -- 从 Finder 接收选择的文件/文件夹并将它们的文件 URL 复制到剪贴板。 -- 如果选择包含超过 1 个项目,则复制的 URL 由 LF 字符分隔。 在运行{输入,参数} 将所有网址设置为“” 告诉应用程序“系统事件” 在输入中重复 f -- 将输入文件/文件夹转换为“系统事件”别名... 将 a 设置为 f 作为别名 -- 并确定“URL”属性的值,即文件URL。 将 thisUrl 设置为一个 URL -- 将文件 URL 添加到整体结果中。 如果 allUrls 的长度为 0 则 将 allUrls 设置为 thisUrl 别的 将 allUrls 设置为 allUrls & linefeed & thisUrl 万一 结束重复 结束告诉 -- 最后,将文件 URL 复制到剪贴板。 将剪贴板设置为 allUrls 结束运行
    • 用描述性名称保存新服务;例如,“将文件 URL 复制到剪贴板”

    当您在 Finder 中按住 Control 键单击项目时,这将使新服务显示在上下文菜单中(取决于定义的服务的数量,无论是在上下文菜单的顶层还是在“服务”子菜单中)。

    如果您想为新服务分配键盘快捷键,请打开“系统偏好设置”,转到“键盘”>“键盘快捷键”>“服务”,然后在此处找到新创建的服务。在条目的右边缘附近单击,然后按所需的组合键。

    【讨论】:

    • 感谢 mklement - 这是一种简洁明了的方法。我喜欢它,AppleScript 工作得很好。不幸的是,无法让它与 Keyboard Maestro 一起使用,所以我会坚持使用另一个,直到我弄清楚它为什么不起作用。
    • @pattulus:谢谢;听起来你有一个可行的解决方案。由于我需要没有键盘大师的类似功能,因此我使用仅内置工具的说明修改了我的答案,以创建 OS X 服务,该服务将使该功能出现在 Finder 的上下文菜单中,并且可以选择使用键盘快捷键调用.
    • 我刚刚再次尝试了这两行代码,它在 Keyboard Maestro 中表现出色 → 感谢您提供这种简洁的方法!
    【解决方案4】:

    好的,如果您使用 Finder 获取选择,则不需要(“python”或“系统事件”)获取 URL

    因为你可以直接从 Finder 中获取 URL

    tell application "Finder" to URL of item 1 of (get selection)
    set the clipboard to the result
    

    【讨论】:

    • 你用这种方法得到的是一个基于 inode 的文件 URL(至少在我的 10.7.4 机器上);例如,file:///.file/id=6707292.176。如果我猜的话,这通常不是你想要的;例如,如果重新创建文件,则 URL 将不再有效(另一方面,如果重命名原始文件,它将继续有效)。
    【解决方案5】:

    AppleScript 编辑器 已经发展成为 脚本编辑器,它现在除了 AppleScript 之外还提供 JavaScript 用于自动化 (JXA)。

    通过 WebKit JavaScriptCore 框架的脚本编辑器提供 encodeURI() 和 decodeUIR()。 encodeURI() 和 decodeUIR() 极大地简化了 Finder URL 的解码和编码。

    脚本编辑器Try-Me示例

    var appFinder = Application('Finder')
    
    var url = appFinder.insertionLocation().url()
    console.log("encoded : " + url)
    console.log("decoded : " + decodeURI(url))
    
    var urlList = appFinder.selection();
    for (idx in urlList) {
      console.log("encoded : " + urlList[idx].url())
      console.log("decoded : " + decodeURI(urlList[idx].url()))
    }
    
    /*  encoded : file:///Volumes/Some%20HD/%E2%80%A2UnicodeName/file.ext */
    /*  decoded : file:///Volumes/Some HD/•UnicodeName/file.ext */
    

    注意:用于自动化的 JavaScript (JXA) 首次在 10.10 OS X Yosemite 中提供。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 2019-09-06
      相关资源
      最近更新 更多