我需要将文件夹及其子文件夹的全部(可见)内容作为列表获取。这可能吗?
看看这有多简单
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
是的,整个内容完全按照你说的做——但它很容易让人窒息 大文件夹,需要很长时间。没关系 一些小事,比如从一个文件夹中提取一种类型的所有文件 知道只会包含少量文件。
递归方法也很有效——但它使用的是“列表文件夹”,并且 它的字典列表说它已被弃用,我们不应该使用它 没有了。
我确定有一个 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
哇,这已经很晚了,但我检查了一下,它有效。
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
对于那些不关心脚本的紧凑性,但关心速度的人,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: