使用 AppleScript 获取完整的目录内容

问题描述 投票:0回答:4

我需要将文件夹及其子文件夹的全部(可见)内容作为列表获取。这可能吗?

list applescript directory subdirectory
4个回答
13
投票

看看这有多简单

  tell application "Finder"
     set file_list to entire contents of (choose folder with prompt "Please select directory.")
   end tell 

如果你想要一个文件名列表,那么你可以这样做

  tell application "Finder"
    set file_list to name of every file of entire contents of (choose folder with prompt "Please select directory.")
   end tell

是的,整个内容完全按照你说的做——但它很容易让人窒息 大文件夹,需要很长时间。没关系 一些小事,比如从一个文件夹中提取一种类型的所有文件 知道只会包含少量文件。

递归方法也很有效——但它使用的是“列表文件夹”,并且 它的字典列表说它已被弃用,我们不应该使用它 没有了。


9
投票

我确定有一个 shell 命令可以更快地执行此操作,但这是纯 Applescript 中的一种方法,可让您完全控制格式化您想要显示的信息。

property kFileList : {}

tell application "Finder"
    set source_folder to choose folder with prompt "Please select directory."
    my createList(source_folder)
end tell

on createList(item_list)
    set the the_items to list folder item_list without invisibles
    set item_list to item_list as string
    repeat with i from 1 to number of items in the the_items
        set the_item to item i of the the_items
        set the_item to (item_list & the_item) as alias
        set this_info to info for the_item
        set file_name to name of this_info
        set end of kFileList to file_name
        if folder of this_info is true then
            my createList(the_item)
        end if
    end repeat
end createList

附带说明,还有一些文件列表应用程序可以比 Applescript 更快地执行此操作。

更新: 作为这次讨论的结果,这里又是函数,但这次使用更新的 API。这可能需要一些清理,但它可以很方便地为我的桌面编目(这对我来说是一个很深很深的文件夹):

property kFileList : {}

tell application "Finder"
    set source_folder to choose folder with prompt "Please select directory."
    my createList(source_folder)
end tell

return kFileList

on createList(mSource_folder)
    set item_list to ""
    
    tell application "System Events"
        set item_list to get the name of every disk item of mSource_folder
    end tell
    
    set item_count to (get count of items in item_list)
    
    repeat with i from 1 to item_count
        set the_properties to ""
        
        set the_item to item i of the item_list
        set the_item to ((mSource_folder & the_item) as string) as alias
        
        tell application "System Events"
            set file_info to get info for the_item
        end tell
        
        if visible of file_info is true then
            set file_name to displayed name of file_info
            set end of kFileList to file_name
            if folder of file_info is true then
                my createList(the_item)
            end if
        end if
        
    end repeat
end createList

1
投票

哇,这已经很晚了,但我检查了一下,它有效。

tell application "Finder" to set folder_root to (choose folder with prompt "Please select directory.")

set fl to {}
dump_folder(folder_root)

on dump_folder(f)
    global fl
    tell application "System Events" to set end of fl to (get the POSIX path of f)
    tell application "Finder" to set nfl to (the items of the contents of f)
    repeat with nf in nfl
        dump_folder(nf as alias)
    end repeat
end dump_folder

fl

0
投票

对于那些不关心脚本的紧凑性,但关心速度的人,AsObjC 版本(由@Shane Stanley 编写,谢谢):

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

-- classes, constants, and enums used
property NSMutableArray : a reference to current application's NSMutableArray
property NSURLIsDirectoryKey : a reference to current application's NSURLIsDirectoryKey
property |NSURL| : a reference to current application's |NSURL|
property NSFileManager : a reference to current application's NSFileManager
property NSURLIsPackageKey : a reference to current application's NSURLIsPackageKey
property NSURLPathKey : a reference to current application's NSURLPathKey
property NSArray : a reference to current application's NSArray
property NSString : a reference to current application's NSString

set theFolder to POSIX path of (path to movies folder)
my entireContentsOf:theFolder includeInvisibles:false includeFiles:true includeFolders:true resultType:"paths"


-- Returns the entire contents of a folder and its subfolders.
-- If includeFolders is false, only files (including packages) will be returned.
-- If includeFiles is false, only folders will be returned. 
-- The resultType parameter takes a string:, "paths" to get POSIX paths, "names" to get just the names, "POSIX names" to get POSIX names (the / character appears as a :), "urls" to get an array of NSURLs, or "files" to get AppleScript file references. The latter is only available under macOS 10.11 and later.
on entireContentsOf:aFileOrPath includeInvisibles:incInvis includeFiles:incFiles includeFolders:incFolders resultType:resType
    set theURL to my makeURLFromFileOrPath:aFileOrPath
    set theOptions to 2 -- NSDirectoryEnumerationSkipsPackageDescendants
    if not incInvis then set theOptions to 6 -- NSDirectoryEnumerationSkipsHiddenFiles
    set theEnumerator to NSFileManager's |defaultManager|()'s enumeratorAtURL:theURL includingPropertiesForKeys:{} options:theOptions errorHandler:(missing value)
    set theURLs to theEnumerator's allObjects()
    if not incFolders then
        set theURLs to my filesAndPackagesInURLArray:theURLs
    else if not incFiles then
        set theURLs to my foldersInURLArray:theURLs
    end if
    return my convertURLs:theURLs resultType:resType
end entireContentsOf:includeInvisibles:includeFiles:includeFolders:resultType:


-- This handler is called by other handlers
on makeURLFromFileOrPath:theFileOrPathInput
    -- make it into a Cocoa object for easier comparison
    set theFileOrPath to (NSArray's arrayWithObject:theFileOrPathInput)'s firstObject()
    if (theFileOrPath's isKindOfClass:(NSString)) as boolean then
        if (theFileOrPath's hasPrefix:"/") as boolean then -- full POSIX path
            return |NSURL|'s fileURLWithPath:theFileOrPath
        else if (theFileOrPath's hasPrefix:"~") as boolean then -- POSIX path needing ~ expansion
            return |NSURL|'s fileURLWithPath:(theFileOrPath's |stringByExpandingTildeInPath|())
        else -- must be HFS path
            return |NSURL|'s fileURLWithPath:(POSIX path of theFileOrPathInput)
        end if
    else if (theFileOrPath's isKindOfClass:(|NSURL|)) as boolean then -- happens with files and aliases in 10.11
        return theFileOrPath
    else -- must be a file or alias
        return |NSURL|'s fileURLWithPath:(POSIX path of theFileOrPathInput)
    end if
end makeURLFromFileOrPath:


-- This handler is called by other handlers
on filesAndPackagesInURLArray:theURLs
    set AsObjCTrue to current application's NSNumber's numberWithBool:true
    set itemURLs to NSMutableArray's array()
    repeat with aURL in theURLs -- is it a directory?
        set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:NSURLIsDirectoryKey |error|:(reference))
        if theValue = AsObjCTrue then -- is it a package?
            set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:NSURLIsPackageKey |error|:(reference))
            if theValue = AsObjCTrue then (itemURLs's addObject:aURL)
        else
            (itemURLs's addObject:aURL)
        end if
    end repeat
    return itemURLs
end filesAndPackagesInURLArray:


-- This handler is called by other handlers
on convertURLs:theURLs resultType:resType
    considering numeric strings
        if resType = "names" then
            return ((((theURLs's valueForKey:"lastPathComponent")'s componentsJoinedByString:(character id 0))'s stringByReplacingOccurrencesOfString:":" withString:"/")'s componentsSeparatedByString:(character id 0)) as list
        else if resType = "POSIX names" then
            return (theURLs's valueForKey:"lastPathComponent") as list
        else if resType = "urls" then
            return theURLs
        else if resType = "files" and AppleScript's version > "2.4" then
            return theURLs as list
        else
            return (theURLs's valueForKey:"path") as list
        end if
    end considering
end convertURLs:resultType:
© www.soinside.com 2019 - 2024. All rights reserved.