【问题标题】:AppleScript: How to check if something is a directory or a fileAppleScript:如何检查某物是目录还是文件
【发布时间】:2013-04-08 15:29:04
【问题描述】:

更新:以下解决方案


假设您有一个来自 Finder 的选定项目列表。假设选择中包含一些文件、文件夹、各种捆绑包,甚至一些应用程序。

现在假设您只想要那些(在 UNIX 术语中)目录的项目。 IE。你只想要在终端中可以cd 的项目。

您可以检查每个项目的kind 属性并查看它是否等于“文件夹”,但这不适用于应用程序包或其他包/包,尽管它们实际上是“文件夹”(目录)

如果项目是实际的文件对象(不是别名),您可以检查每个项目的 class 属性...但也不是总是有效,因为包现在是“文档文件”实例,而应用程序是“应用程序文件”实例。

如果你只有一个别名列表而不是实际的文件对象,那就更糟了,因为你不能检查class 属性;它总是只会说“别名”。

我能想到的唯一解决方案是获取每个项目的 POSIX 路径,并查看它是否有尾部正斜杠,或者将其路径发送到用不同语言编写的脚本,该脚本可以检查是否某事是否是目录。

我觉得这两个想法都很疯狂。检查尾部的正斜杠是非常麻烦和脆弱的,并且将所有内容提供给不同的脚本完全是多余的。


更新:Asmus 下面建议的似乎是唯一一个很好的解决方案,因为 AppleScript 似乎无法在它的自己的:

do shell script "file -b " & filePosixPath

这将返回文件夹、包、应用程序、包等的字符串“目录”。
但请注意(!)对于磁盘,它返回“粘性目录”。

这是一个运行良好的通用函数

on isDirectory(someItem) -- someItem is a file reference
    set filePosixPath to quoted form of (POSIX path of (someItem as alias))
    set fileType to (do shell script "file -b " & filePosixPath)
    if fileType ends with "directory" then return true
    return false
end isDirectory

【问题讨论】:

  • 好吧,我想说最简单的解决方案是将 POSIX 路径交给命令行工具 file,例如file -b /Applications/Safari.app 只返回“目录”。将其合并到do shell script 循环中应该很容易。
  • @Asmus:你可能是对的。在我写完这个问题后,我意识到我可以只做一个快速的 shell 命令,而不是一个完整的 shell 脚本。尽管如此,必须走出 AppleScript 才能弄清楚某些东西是否是目录这样基本的东西似乎很奇怪。我会把这个问题搁置一天左右,在此期间,请随时写下您的评论作为答案,以便您获得积分:)
  • @Flambino 我不能为你的好问题投票,因为我已经用完了所有的投票! :(
  • @fireshadow52:呵呵,重要的是思想——谢谢 :)

标签: applescript


【解决方案1】:

有一个简单的applescript 解决方案。您可以使用系统事件检查某物是否为“包”。

tell application "Finder" to set theItems to (selection) as alias list

set canCDItems to {}
tell application "System Events"
    repeat with anItem in theItems
        if anItem is package folder or kind of anItem is "Folder" or kind of anItem is "Volume" then
            set end of canCDItems to contents of anItem
        end if
    end repeat
end tell
return canCDItems

【讨论】:

  • 有趣!奇怪的是,该词汇被埋在系统事件而不是 Finder 中,但至少它存在。我最终使用了 Asmus 的解决方案,但你回答了最初的问题,所以给你小费(和复选标记)。谢谢!
  • 嗨。创建系统事件是为了减轻 Finder 的负担。基本上,Finder 经常忙于与计算机相关的任务,因此最好尽可能让系统事件而不是 Finder 来做事。因此,系统事件可以完成 Finder 可以做的大部分事情,有时甚至更多。我建议您在考虑使用 Finder 时检查系统事件是否可以代替。
  • 感谢您提供背景信息。我不知道这是系统事件的起源,但这很有意义。我现在将仔细查看系统事件的字典。非常感谢!
  • 我宁愿使用class of anItem is folder和class of anItem is disk,因为字符串是本地化的。
【解决方案2】:

如果变量只是一个字符串,使用这种形式:

on isDirectory(someItem) -- someItem is a string
    set filePosixPath to quoted form of (POSIX path of someItem)
    set fileType to (do shell script "file -b " & filePosixPath)
    if fileType ends with "directory" then return true
    return false
end isDirectory

【讨论】:

    【解决方案3】:

    我今天需要这个,因为我试图将几个差异工具插入 Mountain Lion 的 Finder 中,并想检查所选项目是文件夹还是文件。这对我有用:

    tell application "Finder"
      set sel1 to the selection
      set class1 to class of (item 1 of sel1)
      set cs to (class1 as string)
      ...
      if cs = "folder" or cs contains "class cfol" then
        set choice to display alert "Which tool?" buttons {"opendiff", "diffmerge"}
        set tool to (button returned of choice)
    

    我发现我需要针对这两种情况测试 cs,这取决于我是在 AppleScript 编辑器中运行还是由于单击 Finder 上的工具栏按钮而导致。远非最整洁,但比以前的仅限 AppleScript 的解决方案更短,这将是我的替代建议

    on isDirectory(someItem)
      ((class of someItem) as string) contains "fol"
    end isDirectory
    

    欢迎在所有情况下进行全面测试!

    【讨论】:

      【解决方案4】:

      Standard Additions 提供此功能(无需系统事件):

      set isBundleType to package folder of (info for (choose file))
      

      【讨论】:

        猜你喜欢
        • 2018-12-18
        • 2015-06-01
        • 1970-01-01
        • 2011-04-20
        • 2011-05-31
        • 1970-01-01
        • 2011-12-26
        • 2013-08-14
        • 2015-07-30
        相关资源
        最近更新 更多