在已连接服务器卷(又称“共享”)中搜索
刚好碰到过类似的需求,给你整理几个实用的方法,覆盖Shell、AppleScript和JavaScript三种场景,完美替代手动逐个搜索挂载卷的麻烦:
Shell 脚本方案
挂载的卷默认都存在 /Volumes 目录下,所以直接基于这个目录写批量搜索命令就行,简单高效。
基础搜索命令
- 按文件名搜索:
find /Volumes -type f -name "你的文件名关键词" 2>/dev/null
- 按文件内容搜索:
grep -r "你的内容关键词" /Volumes 2>/dev/null
2>/dev/null 是用来忽略权限不足或无法访问的卷的错误信息,避免输出一堆干扰内容。
封装成便捷函数
如果经常用,可以把搜索逻辑封装成Shell函数,加到你的 ~/.bash_profile 或 ~/.zshrc 里:
search_all_volumes() { if [ $# -eq 0 ]; then echo "用法: search_all_volumes <搜索关键词>" echo "示例: search_all_volumes \"TODO\" --include=\"*.md\"" return 1 fi grep -r "$@" /Volumes 2>/dev/null }
之后直接在终端输入 search_all_volumes "要找的内容" 就能批量搜所有卷,还能加 --include="*.txt" 这类参数限定文件类型。
AppleScript 方案
如果你更喜欢图形化的交互,AppleScript可以做带弹窗的搜索工具,和Finder的操作逻辑更贴近:
set searchQuery to text returned of (display dialog "请输入要搜索的关键词:" default answer "") set volumeList to list folder "Macintosh HD:Volumes:" without invisibles repeat with vol in volumeList set volPath to "/Volumes/" & vol try -- 用shell命令实现高效搜索,返回包含关键词的文件名 set foundItems to paragraphs of (do shell script "find " & quoted form of volPath & " -type f -exec grep -l " & quoted form of searchQuery & " {} \\; 2>/dev/null") if foundItems is not {} then display dialog "在卷「" & vol & "」中找到:" & return & (join foundItems with return) buttons {"继续"} default button 1 end if on error errMsg display dialog "访问卷「" & vol & "」时出错:" & errMsg buttons {"确定"} default button 1 end try end repeat -- 辅助函数:把列表转成带换行的字符串 on join(lst, delimiter) set prevTIDs to AppleScript's text item delimiters set AppleScript's text item delimiters to delimiter set joinedText to lst as text set AppleScript's text item delimiters to prevTIDs return joinedText end join
把这段脚本保存成 .scpt 文件,双击就能运行,会弹出对话框让你输入关键词,然后逐个卷搜索并弹窗显示结果,还会处理权限错误。
JavaScript for Automation (JXA) 方案
如果你熟悉JavaScript,可以用JXA(Mac原生支持的JS自动化)来实现,写法更灵活:
const app = Application.currentApplication(); app.includeStandardAdditions = true; try { let searchQuery = app.displayDialog("请输入要搜索的关键词:", { defaultAnswer: "", buttons: ["取消", "搜索"], defaultButton: "搜索" }).textReturned; // 获取所有可见的挂载卷 let volumes = app.listFolder("/Volumes", { invisibles: false }); volumes.forEach(vol => { let volPath = `/Volumes/${vol}`; try { // 调用shell命令执行搜索 let foundItems = app.doShellScript( `find ${app.quotedForm(volPath)} -type f -exec grep -l ${app.quotedForm(searchQuery)} {} \\; 2>/dev/null` ).split("\n"); // 过滤空结果,避免弹窗干扰 if (foundItems.length > 0 && foundItems[0] !== "") { app.displayDialog(`在卷「${vol}」中找到:\n${foundItems.join("\n")}`, { buttons: ["下一个"], defaultButton: "下一个" }); } } catch (err) { app.displayDialog(`访问卷「${vol}」时出错:${err.message}`, { buttons: ["忽略"], defaultButton: "忽略" }); } }); } catch (err) { // 用户点击取消时的处理 if (err.errorNumber !== -128) { app.displayDialog(`搜索出错:${err.message}`); } }
这个脚本和AppleScript的功能类似,但用JS的语法写,处理逻辑更直观,适合有JS基础的用户。
一些额外提示
- 如果只需要搜索共享卷(就是Finder里「Shared」下的那些),可以把搜索目录改成
/Volumes下的共享卷子集,但一般挂载的卷都会在/Volumes里,所以直接搜整个目录就行。 - 要是搜索速度慢,可以加
-maxdepth参数限制搜索深度,比如find /Volumes -maxdepth 3 ...。 - 权限问题:如果有些卷是加密的或者没有访问权限,脚本里的错误处理会跳过这些卷,不会中断整个搜索流程。
内容的提问来源于stack exchange,提问作者Ryul
相关产品推荐
相关产品推荐

