macOS 文件搜索工具封装 — 支持 AppleScript 自动化、Shell 脚本钩子、URL Scheme 唤起和内置 HTTP API。
适用场景: 深度文件搜索、文件名/内容/元数据查询、按大小/日期/类型筛选、批量操作。
ProFind 是 macOS 上的增强搜索工具,同时支持:
bash
if [ -d "/Applications/ProFind.app" ]; then
echo "ProFind 已安装: $(defaults read /Applications/ProFind.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null)"
else
echo "ProFind 未安装,请从 App Store 下载:https://apps.apple.com/app/id1559203395"
fi
功能说明find_files按文件名搜索,支持 glob/正则find_content全文件内容搜索(支持 Spotlight 元数据)find_advanced高级组合搜索(大小/日期/类型/UTI/标签等)run_script执行 ProFind 脚本钩子处理搜索结果open_search_window打开 ProFind 搜索窗口(可预填查询词)query_api通过 HTTP API 程序化搜索
text
用户查询 → 自动判断使用哪种搜索 → 执行
情况推荐策略找已知名称的文件find_files(Spotlight,毫秒级)搜索文件内容/元数据find_content需要多条件组合find_advanced需要对结果批量操作run_script需要 UI 交互open_search_window
基于 Spotlight 索引,毫秒级返回。
bash
# 基本搜索
osascript << 'EOF'
tell application "ProFind"
activate
open location "profind:search?name=test&path=~/Documents"
end tell
EOF
# 在指定路径搜索(使用 find 命令找 ProFind 窗口内路径)
# ProFind 支持通过 open location 唤起并传入搜索条件
URL Scheme 格式:
text
profind:search?name=<搜索词>&path=<路径>&scope=<范围>
参数说明示例name搜索文件名test.txt、 *.pdf``path搜索根路径(可选)~/Documents、 /Users/Admin``scope搜索范围all、 home、 selected、 hidden
使用 Spotlight 查询引擎,支持按内容、作者、UTI、元数据搜索。
bash
osascript << 'EOF'
tell application "ProFind"
activate
-- 搜索文件名含 "invoice" 且大小 > 1MB 的 PDF
open location "profind:search?name=invoice&kind=PDF&size=larger:1MB"
-- 搜索内容含关键字(Spotlight 元数据查询)
open location "profind:search?name=meeting&meta=content:brainstorm"
-- 按修改日期搜索(最近 7 天内)
open location "profind:search?name=report&date=modified:~week"
-- 按标签搜索
open location "profind:search?name=doc&label=red"
end tell
EOF
URL 参数(内容/元数据搜索):
参数说明示例kind文件类型PDF、 image、 document、 folder``metaSpotlight 元数据查询content:<词>、 author:<人>``size文件大小larger:1MB、 smaller:100KB、 equal:5MB``date日期范围modified:~week、 created:~month、 ~year、 ~3month``label标签颜色red、 orange、 yellow、 green、 blue、 purple、 gray``contains文件内容包含contains:text to find
ProFind 支持的高级搜索条件,通过 AppleScript 脚本直接构建搜索窗口内容。
bash
osascript << 'EOF'
tell application "ProFind"
activate
-- 打开搜索窗口
set queryWin to make new query window with properties {search text:"*.swift"}
-- 设置高级搜索参数(通过 GUI 脚本或直接参数)
open location "profind:search?name=*.swift&path=/Users&size=larger:0&date=modified:~month&scope=home"
end tell
EOF
搜索条件速查:
条件URL 值说明文件名包含name=test支持 glob *.pdf、正则 file[0-9]+隐藏文件scope=all包含隐藏文件仅应用kind=application只搜应用仅文件夹kind=folder只搜文件夹排除文件夹exclude:/Volumes/Network排除指定路径正则搜索name=regex:^doc_[0-9]{4}$使用正则表达式Spotlight 查询kind=spotlightmetadata直接写 mdimporter 查询
常用文件类型(Kind):
text
PDF、document、image、movie、music、archive、code、application、folder
Spotlight 元数据类型:
text
content、author、comment、creator、title、subject、keyword、album、artist
ProFind 的"脚本钩子"(Script Actions)功能:搜索完成后对结果文件执行自定义脚本。
内置脚本钩子(Sample Scripts):
text
/Applications/ProFind.app/Contents/Resources/Sample Scripts/
脚本功能Less In Terminal.scpt在 Terminal 用 less 分页查看路径Move To Trash.scpt将选中文件移至废纸篓Say Paths.scpt朗读文件路径Show Strings In Terminal.scpt显示文件的字符串资源Open in iTunes.scpt在 iTunes 中打开音频文件Word Count.shell统计文件字数Print Paths.shell打印文件路径mail.scpt发送文件路径邮件duckduckgo.scpt用 DuckDuckGo 搜索文件名
通过 ProFind 菜单配置脚本:
fileItem(当前文件)和 fileList(所有选中文件)脚本接收的 AppleScript 参数:
参数名类型说明currentFile / fileItemPOSIX file当前选中的文件路径fileListlist of POSIX file所有选中的文件路径列表args / argsWithoutPathstext用户传入的额外参数(空格分隔)urlArgumentstext解析后的 URL 参数numberOfArgsinteger参数个数
自定义脚本示例(Shell — 批量重命名):
bash
#!/bin/bash
# ProFind Shell Script Hook 示例
# 放在 ~/Library/Scripts/ProFind/ 下即可在 ProFind 中调用
for file in "$@"; do
echo "处理文件: $file"
# 替换空格为下划线
newname=$(echo "$(basename "$file")" | sed 's/ /_/g')
dir=$(dirname "$file")
if [ "$newname" != "$(basename "$file")" ]; then
mv "$file" "$dir/$newname"
echo "重命名为: $newname"
fi
done
自定义脚本示例(AppleScript — 发送邮件):
applescript
-- 放在 ~/Library/Scripts/ProFind/MailFilePath.scpt
-- 使用方式:在 ProFind 中选中文件 → Scripts → MailFilePath
-- 参数格式:: mail "收件人" "主题"
on open theFiles
tell application "Mail"
set theMessage to make new outgoing message with properties ¬
{subject:"ProFind 文件", content:"附件文件路径:" & linefeed}
tell theMessage
repeat with aFile in theFiles
set content of theMessage to ¬
(content of theMessage) & (POSIX path of aFile) & linefeed
end repeat
set visible to true
activate
end tell
end tell
end open
通过 run script 执行(AppleScript 调用):
bash
osascript << 'EOF'
-- 调用 ProFind 的 DuckDuckGo 脚本搜索文件名
tell application "ProFind"
open location "profind:search?name=macOS Ventura&script=duckduckgo"
end tell
EOF
打开 ProFind 主窗口,支持预填充搜索条件。
bash
# 打开 ProFind(全新窗口)
osascript -e 'tell application "ProFind" to activate'
# 带搜索条件打开
osascript << 'EOF'
tell application "ProFind"
activate
open location "profind:search?name=report&kind=PDF&path=~/Documents"
end tell
EOF
# 打开并显示高级搜索面板
osascript << 'EOF'
tell application "ProFind"
activate
-- 打开搜索窗口后通过菜单触发高级搜索
tell process "ProFind"
keystroke "f" using {command down, option down}
end tell
end tell
EOF
ProFind 快捷键:
快捷键功能Cmd+F新建搜索Cmd+O打开选中文件Cmd+Return打开选中项Space快速预览(QLGenerator)Cmd+Shift+G前往路径Cmd+,偏好设置
ProFind 内置 Media Server(UPnP/DLNA 媒体服务器),运行于 端口 54812,支持 SOAP 协议搜索。
⚠️ 重要说明: Media Server 是 ProFind 搜索结果的 UPnP 暴露接口,不是独立的文件索引 API。需要先在 ProFind UI 中执行搜索,结果才会出现在 Media Server 中。
启用方式: ProFind → 偏好设置 → Media Server → 勾选启用
协议: UPnP SOAP(非 REST),需通过 SOAP Action 调用:
bash
PORT=54812
# ① 获取搜索能力
curl -s --max-time 10 -X POST "http://localhost:$PORT/ContentDirectory/control" \
-H "Content-Type: text/xml; charset=utf-8" \
-H 'SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#GetSearchCapabilities"' \
-d '<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetSearchCapabilities xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"/>
</s:Body>
</s:Envelope>'
# ② 搜索文件(dc:title = 文件名)
curl -s --max-time 15 -X POST "http://localhost:$PORT/ContentDirectory/control" \
-H "Content-Type: text/xml; charset=utf-8" \
-H 'SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Search"' \
-d '<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Search xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<ContainerID>0</ContainerID>
<SearchCriteria>(dc:title contains "keyword")</SearchCriteria>
<SortCriteria></SortCriteria>
</u:Search>
</s:Body>
</s:Envelope>'
# ③ 浏览目录结构
curl -s --max-time 10 -X POST "http://localhost:$PORT/ContentDirectory/control" \
-H "Content-Type: text/xml; charset=utf-8" \
-H 'SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"' \
-d '<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<ObjectID>0</ObjectID>
<BrowseFlag>BrowseDirectChildren</BrowseFlag>
<Filter>*</Filter>
<StartingIndex>0</StartingIndex>
<RequestedCount>20</RequestedCount>
<SortCriteria></SortCriteria>
</u:Browse>
</s:Body>
</s:Envelope>'
SOAP Action 速查:
Action说明端口GetSearchCapabilities获取支持的元数据字段54812Search按文件名/元数据搜索54812Browse浏览索引目录结构54812
所有搜索操作通过 osascript + URL Scheme 执行:
bash
profind_search() {
local query="$1"
local kind="${2:-}"
local path="${3:-}"
local url="profind:search?name=${query}"
[ -n "$kind" ] && url="${url}&kind=${kind}"
[ -n "$path" ] && url="${url}&path=${path}"
osascript -e "tell application \"ProFind\" to open location \"$url\"" &
}
处理 ProFind 脚本钩子:
bash
cat > ~/Library/Scripts/ProFind/MyScript.scpt << 'APPLESCRIPT'
on open theFiles
repeat with aFile in theFiles
-- 处理每个文件
do shell script "echo " & (POSIX path of aFile)
end repeat
end open
APPLESCRIPT
bash
profind_search() {
local query="$1"
local url="profind:search?name=${query}&kind=PDF&date=modified:~month"
osascript -e "tell application \"ProFind\" to open location \"$url\""
}
profind_search "report"
bash
osascript << 'EOF'
tell application "ProFind"
activate
open location "profind:search?name=*&kind=movie&size=larger:10MB&scope=all"
end tell
EOF
bash
osascript << 'EOF'
tell application "ProFind"
activate
open location "profind:search?name=*.swift&path=/Users/Admin/Projects&exclude:/Users/Admin/Projects/node_modules"
end tell
EOF
bash
# 先用 Spotlight 快速定位,再用脚本批量处理
osascript << 'EOF'
tell application "ProFind"
activate
open location "profind:search?name=*.log&size=larger:1MB&path=/Users/Admin"
end tell
EOF
# 用户在 ProFind 界面中选择文件 → Scripts → "Move To Trash" 批量删除
错误原因解决方案Application isn't runningProFind 未安装/启动open /Applications/ProFind.app``URL could not be openedURL Scheme 格式错误检查 profind: 参数格式Permission denied权限不足系统偏好设置 → 隐私与安全性 → 完全磁盘访问No resultsSpotlight 索引为空运行 mdutil -s / 重建索引Script error脚本钩子执行失败检查脚本语法和参数
macOS 10.14+
ProFind 1.0+(App Store 下载)
完全磁盘访问权限(系统偏好设置 → 隐私与安全性 → 完全磁盘访问)
文件路径ProFind 应用/Applications/ProFind.app示例脚本/Applications/ProFind.app/Contents/Resources/Sample Scripts/用户脚本~/Library/Scripts/ProFind/偏好设置~/Library/Preferences/com.zeroonetwenty.ProFind.plist日志~/Library/Logs/ProFind/索引数据库~/.ProFind/
bash
# 在 ~/.zshrc 中添加 alias:
alias profind='open -a ProFind'
alias profind-search='profind_search' # 见上方函数定义'