AppleScript:如何检查某个内容是目录还是文件

AppleScript:如何检查某个内容是目录还是文件,applescript,Applescript,更新:下面的解决方案 假设您有Finder中选定项目的列表。假设选择中包含一些文件、文件夹、各种捆绑包,甚至一些应用程序 现在假设您只想要那些(在UNIX术语中)目录中的项目。也就是说,您只需要可以在终端中cd的项目 您可以检查每个项目的kind属性,看看它是否等于“Folder”,但这不适用于应用程序包或其他包/包,尽管它们实际上是“folders”(目录) 如果项目是实际的文件对象(不是别名),则可以检查每个项目的类属性。。。但这也并不总是有效,因为捆绑包现在是“文档文件”实例,而应用程序

更新:下面的解决方案


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

现在假设您只想要那些(在UNIX术语中)目录中的项目。也就是说,您只需要可以在终端中
cd
的项目

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

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

如果您只有别名列表而没有实际的文件对象,则情况会更糟,因为您无法检查
class
属性;它总是说“别名”

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

我觉得这两个想法都很疯狂。检查尾随的正斜杠是非常粗糙和脆弱的,将所有内容输入到不同的脚本完全是过火了


更新:Asmus在下面提出的建议似乎是唯一一个好的解决方案,因为AppleScript似乎无法自行解决这个问题:

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

这是一个通用函数,它工作得很好

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

有一个简单的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

今天我需要这个,因为我正试图将几个diff工具插入到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 only解决方案要短,这将是我的备选方案

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

欢迎所有情况下的全面测试结果

如果变量只是一个字符串,请使用以下形式:

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

标准新增功能提供了以下功能(无需系统事件):


嗯,我认为最简单的解决方案是将POSIX路径交给命令行工具
file
,例如
file-b/Applications/Safari.app
只返回“directory”。将其合并到
do shell脚本
循环中应该很容易。@Asmus:你可能是对的。在我写了这个问题之后,我意识到我可以只做一个快速的shell命令,而不是一个完整的shell脚本。尽管如此,要在AppleScript之外找出一些基本的东西,比如某个东西是否是目录,这似乎很奇怪。我将把这个问题保留一天左右,在此期间,请随意给你写评论作为回答,这样你就可以得到答案:)@Flambino我不能给你的好问题投上高票,因为我已经用光了我所有的选票!:(@fireshadow52:Heh,重要的是思想——谢谢:)有趣!奇怪的是,这些词汇被埋藏在系统事件中而不是查找器中,但至少它是存在的。我最终使用了阿斯莫斯的解决方案,但你回答了最初的问题,所以给你一个小提示(和复选标记)。谢谢你好创建系统事件是为了减轻查找器的负载。基本上,查找器经常忙于与计算机相关的任务,因此,如果可能,最好让系统事件来做事情,而不是查找器。因此,系统事件可以完成查找器可以完成的大部分事情,有时甚至更多。我建议您在考虑使用Finder的任何时候检查系统事件是否可以替代它。感谢您提供的背景信息。我不知道这是系统事件的起源,但这很有道理。现在,我将仔细查看系统事件字典。非常感谢!我宁愿使用anItem的
类为folder
类为disk
,因为字符串是本地化的。
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
set isBundleType to package folder of (info for (choose file))