Spotlightが簡単に見つけられないファイルを発見する方法
Spotlightはあらゆるファイルを検索する能力を持っているはずなんだけど、思い付いたキーワードをそのまま入力しているだけでは、存在するはずのファイルが見つからない、という状況によく陥る。
キーワードのみで検索
例えば、最近インストールしたsaykanaコマンドをSpotlight(control-space)で検索してみると...
- ダウンロードしたzipファイルや解凍したインストーラー、関連するwebページは見つかるけど、
- 肝心のsaykanaコマンドはヒットしないのだ。
- 実際にはちゃんと /usr/local/bin/SayKana として存在する。
もう一つ、bashの設定ファイルも検索してみた。
- こちらも発見できないが、実際にはちゃんと ~/.bash_profile は存在する。
検索条件を追加する
- 今度は、Spotlightのウィンドウ検索(control-option-space)で「システムファイルを含む」条件で検索してみた。
-
- すると、saykanaコマンドがヒットした!
- しかし、.bash_profileは見つからない...。
- そこで、条件を変更して「ファイルの可視属性が不可視の項目」条件で検索してみた。
-
- すると、.bash_profileもヒット!
- 注意)「ファイルの可視属性が不可視の項目」にすると、検索が完了するまで相当時間がかかるし、CPUの負荷も大きかった。
- すると、.bash_profileもヒット!
- つまり、キーワードのみで検索した時には、少なくとも以下のデフォルト条件の元で検索されているということになる。
- 「システムファイルを含まない」
- 「ファイルの可視属性が可視の項目」
- しかし、これでもまだ、あらゆるファイルは検索できていない。「swapfile」で検索してみると...
- システムファイルやファイルの可視属性の条件を変えてみても、一向にヒットしない。
- 実際にはちゃんと /private/var/vm/swapfile0 が存在するのだが...。
ターミナルでSpotlight検索
- 結局、GUIの環境からswapfile0をヒットすることはできなくて(アクセス権限がないため)、その検索はターミナルコマンドに委ねる必要があった。
- mdfind を管理者権限で実行して、ようやくヒットした。
$ sudo mdfind 'kMDItemFSName == "swapfile*"' /private/var/vm/swapfile0
- mdfindの検索条件の指定方法は、本家Appleに詳細があった。
- mdfindの実際の使用例は、MacWikiの以下のページが詳しい。
mdfindの検証
- ワイルドカード*条件と、肯定OR否定条件で、結果は異なる。
- kMDItemSupportFileType == *
- kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile
-
- 自分勝手な予想
- kMDItemSupportFileType == * では、kMDItemSupportFileType属性が必ず存在することが期待されるけど、
- kMDItemSupportFileType != MDSystemFile なら、kMDItemSupportFileType属性が無くてもOKだから?
- 自分勝手な予想
$ sudo mdfind "kMDItemFSName == '*swapfile*'c && kMDItemSupportFileType == MDSystemFile" # 結果なし $ sudo mdfind "kMDItemFSName == '*swapfile*'c && kMDItemSupportFileType != MDSystemFile" /private/var/vm/swapfile0 $ sudo mdfind "kMDItemFSName == '*swapfile*'c && kMDItemSupportFileType == *" # 結果なし
- 管理者権限あり・無しで、結果は異なる。
$ sudo mdfind "kMDItemFSName == '*swapfile*'c" /private/var/vm/swapfile0 $ mdfind "kMDItemFSName == '*swapfile*'c" # 結果なし $ ls -la /private/var/vm/swapfile0 -rw------T 1 root wheel 67108864 6 17 14:00 /private/var/vm/swapfile0
- 条件は || で合算できる。
- 以下の条件は、異なる結果になる。
$ sudo mdfind "kMDItemFSName == '*bash_*'c && kMDItemSupportFileType == MDSystemFile" /Users/zari/Library/Logs/CrashReporter/bash_2009-05-20-102702_zari-MacBook.crash /Users/zari/Library/Application Support/CrashReporter/bash_10227A05-A0C8-548B-96A3-FCABD2553B5A_CrashHistory.plist /usr/share/zsh/4.3.4/functions/_bash_completions $ sudo mdfind "kMDItemFSName == '*bash_*'c && kMDItemSupportFileType != MDSystemFile" /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Frat.cis.k.hosei.ac.jp%2Farticle%2Flinux%2Fbash_intro.html.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.boaro.jp%2Flinux%2Fbash%2Fbash_script.html.webhistory $ sudo mdfind "kMDItemFSName == '*bash_*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile)" /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Frat.cis.k.hosei.ac.jp%2Farticle%2Flinux%2Fbash_intro.html.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.boaro.jp%2Flinux%2Fbash%2Fbash_script.html.webhistory /Users/zari/Library/Logs/CrashReporter/bash_2009-05-20-102702_zari-MacBook.crash /Users/zari/Library/Application Support/CrashReporter/bash_10227A05-A0C8-548B-96A3-FCABD2553B5A_CrashHistory.plist /usr/share/zsh/4.3.4/functions/_bash_completions $ sudo mdfind "kMDItemFSName == '*bash_*'c" /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Frat.cis.k.hosei.ac.jp%2Farticle%2Flinux%2Fbash_intro.html.webhistory /usr/share/zsh/4.3.4/functions/_bash_completions /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.boaro.jp%2Flinux%2Fbash%2Fbash_script.html.webhistory
- 不可視属性には、kMDItemFSInvisible == * あるいは kMDItemFSInvisible == 1 が必要
$ sudo mdfind "kMDItemFSName == '*bash_*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *)" Password: /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Frat.cis.k.hosei.ac.jp%2Farticle%2Flinux%2Fbash_intro.html.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.boaro.jp%2Flinux%2Fbash%2Fbash_script.html.webhistory /Users/zari/Library/Logs/CrashReporter/bash_2009-05-20-102702_zari-MacBook.crash /Users/zari/Library/Application Support/CrashReporter/bash_10227A05-A0C8-548B-96A3-FCABD2553B5A_CrashHistory.plist /usr/share/zsh/4.3.4/functions/_bash_completions /Users/zari/.bash_profile
- 管理者権限と言えども、アクセス権がなければヒットしない。
$ mdfind "kMDItemFSName == '*bash_*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *)" /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Frat.cis.k.hosei.ac.jp%2Farticle%2Flinux%2Fbash_intro.html.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.boaro.jp%2Flinux%2Fbash%2Fbash_script.html.webhistory /Users/zari/Library/Logs/CrashReporter/bash_2009-05-20-102702_zari-MacBook.crash /Users/zari/Library/Application Support/CrashReporter/bash_10227A05-A0C8-548B-96A3-FCABD2553B5A_CrashHistory.plist /usr/share/zsh/4.3.4/functions/_bash_completions /Users/zari/.bash_history /Users/zari/.bash_profile $ ls -la ~/.bash_* -rw------- 1 zari staff 23963 6 17 17:04 /Users/zari/.bash_history -rw-r--r-- 1 zari staff 231 5 19 15:37 /Users/zari/.bash_profile
属性を含めた検索ワードにする
検索キーワード中に、属性情報を含めることもできるのであった。属性名はコロン:で区切って条件として追加する。
- 「.bash_ invisible:1」
-
- 注意)「invisible:1」にすると、検索が完了するまで相当時間がかかるし、CPUの負荷も大きかった。
-
ところが、「システムファイルを含む」という属性については、どのようにキーワードに含めて表現するのか分からなかった...。以下のように書いてみたが、システムファイルは検索されない...。
- 「saykana kMDItemSupportFileType:MDSystemFile」
-
-
- その他のSpotlightの属性名については以下のページが相当に詳しい。(素晴らしい情報に感謝です!)
- Spotlightを使いこなす! - Part2 : Macはじめました。
-
検索ウィンドウの条件をAND、OR、NOTで繋ぐ
- 今まで知らなかったが、検索ウィンドウで複数の条件を利用する時、AND、OR、NOTを指定できる。
- optionキーを押しながら + ボタン( … に変化する)をクリックすればOK。
- これを利用すれば、かなり複雑な条件でも検索できそう。
- デフォルトでは複数の条件はANDで繋げて評価されるようだ。
Finderのデフォルト検索条件を変更する
- 検索条件は、スマートフォルダとして保存しておくことができるが、検索ワードまで含めた固定された条件になってしまう。
- 上記スマートフォルダを、Finderから command-F で検索した時のデフォルト条件として利用することもできる。
- Finderの中身を書き換えることになるので、バックアップ等して慎重に行うべきだが、以下の手順で実現できる。
- 好みの条件をスマートフォルダとして登録する。
- (例:~/Library/Saved Searches/my_default_smart.savedSearch)
- .savedSearchファイルは、テキストエディットで開いて、その詳細を確認することもできる。
$ cd /System/Library/CoreServices/Finder.app/Contents/Resources/ # 元ファイルをバックアップする $ sudo cp default_smart.plist default_smart.plist.bak # スマートフォルダをデフォルトにセットする $ sudo cp ~/Library/Saved\ Searches/my_default_smart.savedSearch default_smart.plist
-
- 以上で、Finderから検索した時、my_default_smart.savedSearchの条件が表示されるようになる。
$ cd /System/Library/CoreServices/Finder.app/Contents/Resources/ # Finderの初期状態に戻したい時は以下を実行する $ sudo cp default_smart.plist.bak default_smart.plist
結論
- GUI環境のSpotlight(control-space、control-option-space、command-F)では、全てのファイルを漏れなく検索することが出来ない。
- ターミナルからmdfindコマンドを適切な条件で実行すれば、たぶん、全てのファイルが検索できていると考えている。(アクセス権限があれば)
- だからGUI環境のSpotlightはダメとは考えずに、その特性を活かした検索で利用すればとても便利。
- 辞書やホーム内の自分で作成したファイルの検索については、検索ワードのみで、素早く・確実に結果が返ってくる。
- ファイル名でルート以下を検索する時は、以下の可能性に気を付ける。
- 管理者権限でないとアクセスできないファイルかもしれない。
- 大文字小文字の違いでヒットしないかもしれない。
- 検索ワードは、前方一致・後方一致・含むのどの条件でヒットするのか?
- システムファイルかどうか?
- 不可視ファイルかどうか?
- 例:ファイル名にrubyを含む全てのファイルにヒットさせる為には、以下のような検索条件を設定してみた。
$ sudo mdfind 'kMDItemFSName == "*ruby*"c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *)'
mdfind_allコマンドを作る。
時には漏れなくファイルを検索したいこともあるけど、このままでは、また悩むことになってしまいそう。(きっと1ヵ月後には、mdfindのことなんて忘れてしまう。)そこで、mdfind_allコマンドを次回の検索に備えて作っておくことにした。
- 以下を /usr/local/bin/mdfind_all として保存。
#! /bin/sh echo mdfind "kMDItemFSName == '*$1*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *)" echo '管理者権限が必要なファイルを検索するには sudo で認証が必要です。' echo Running... echo mdfind "kMDItemFSName == '*$1*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *)"
- 実行権限を追加して出来上がり。
$ cd /usr/local/bin $ chmod a+x mdfind_all $ ls -l mdfind_all -rwxr-xr-x@ 1 zari wheel 104 6 17 22:55 mdfind_all
- 利用例
- 不可視属性も含めて検索するため時間がかかる。
- growlnotifyを続けて実行すると良いかも。(終わった時にgrowlが教えてくれる。)
$ mdfind_all saykana; growlnotify "mdfind_all完了!" mdfind kMDItemFSName == '*saykana*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *) 管理者権限が必要なファイルを検索するには sudo で認証が必要です。 Running... /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fhajimemasita.blogspot.com%2F2009%2F05%2Fmacsaykana.html.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.a-quest.com%2Faquestalk%2Fsaykana%2Findex.html.webhistory /Users/zari/Downloads/saykana0111.pkg.zip /Users/zari/Downloads/SayKana0111.pkg /Library/Receipts/SayKana0111.pkg /usr/local/bin/SayKana /Users/zari/Library/Logs/CrashReporter/saykana_2009-06-01-051549_zari-MacBook.crash /Users/zari/Library/Logs/CrashReporter/saykana_2009-06-01-051601_zari-MacBook.crash /Users/zari/Library/Logs/CrashReporter/saykana_2009-05-30-115632_zari-MacBook.crash /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.a-quest.com%2Faquestalk%2Fsaykana%2Flicence_saykana.pdf.webhistory /Users/zari/Library/Application Support/CrashReporter/saykana_10227A05-A0C8-548B-96A3-FCABD2553B5A_CrashHistory.plist /Users/zari/Documents/saykana音声記号仕様.pdf /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.google.com%2Fsearch?q=saykana&ie=UTF-8&oe=UTF-8.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.a-quest.com%2Faquestalk%2Fsaykana%2F.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.google.com%2Fsearch?client=safari&rls=ja-jp&q=saykana&ie=UTF-8&oe=UTF-8.webhistory /Users/zari/Library/Scripts/SayKANA.scpt /Users/zari/Library/Logs/CrashReporter/saykana_2009-06-02-115112_zari-MacBook.crash
$ mdfind_all bash_; growlnotify "mdfind_all完了!" mdfind kMDItemFSName == '*bash_*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *) 管理者権限が必要なファイルを検索するには sudo で認証が必要です。 Running... /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Frat.cis.k.hosei.ac.jp%2Farticle%2Flinux%2Fbash_intro.html.webhistory /Users/zari/Library/Caches/Metadata/Safari/History/http:%2F%2Fwww.boaro.jp%2Flinux%2Fbash%2Fbash_script.html.webhistory /Users/zari/Library/Logs/CrashReporter/bash_2009-05-20-102702_zari-MacBook.crash /Users/zari/Library/Application Support/CrashReporter/bash_10227A05-A0C8-548B-96A3-FCABD2553B5A_CrashHistory.plist /usr/share/zsh/4.3.4/functions/_bash_completions /Users/zari/.bash_history /Users/zari/.bash_profile
$ sudo mdfind_all swapfile; growlnotify "mdfind_all完了!" Password: mdfind kMDItemFSName == '*swapfile*'c && (kMDItemSupportFileType == MDSystemFile || kMDItemSupportFileType != MDSystemFile || kMDItemFSInvisible == *) 管理者権限が必要なファイルを検索するには sudo で認証が必要です。 Running... /private/var/vm/swapfile0
メタデータ属性を確認する
- mdlsコマンドで、ファイルやフォルダのメタデータ属性の詳細を確認できる。
$ mdls /usr/local/bin/SayKana kMDItemContentCreationDate = 2009-05-16 14:55:47 +0900 kMDItemContentModificationDate = 2009-05-16 14:55:47 +0900 kMDItemContentType = "public.unix-executable" kMDItemContentTypeTree = ( "public.unix-executable", "public.data", "public.item", "public.executable" ) kMDItemDisplayName = "SayKana" kMDItemFSContentChangeDate = 2009-05-16 14:55:47 +0900 kMDItemFSCreationDate = 2009-05-16 14:55:47 +0900 kMDItemFSCreatorCode = "" kMDItemFSFinderFlags = 0 kMDItemFSHasCustomIcon = 0 kMDItemFSInvisible = 0 kMDItemFSIsExtensionHidden = 0 kMDItemFSIsStationery = 0 kMDItemFSLabel = 0 kMDItemFSName = "SayKana" kMDItemFSNodeCount = 0 kMDItemFSOwnerGroupID = 80 kMDItemFSOwnerUserID = 0 kMDItemFSSize = 422764 kMDItemFSTypeCode = "" kMDItemKind = "Unix 実行ファイル" kMDItemLastUsedDate = 2009-05-16 14:55:47 +0900 kMDItemSupportFileType = ( MDSystemFile ) kMDItemUsedDates = ( 2009-05-16 00:00:00 +0900 )
$ sudo mdls /private/var/vm/swapfile0
kMDItemContentType = ""
kMDItemFSContentChangeDate = 2009-06-17 14:00:59 +0900
kMDItemFSCreationDate = 2009-06-17 14:00:59 +0900
kMDItemFSCreatorCode = ""
kMDItemFSFinderFlags = 0
kMDItemFSHasCustomIcon = 0
kMDItemFSInvisible = 0
kMDItemFSIsExtensionHidden = 0
kMDItemFSIsStationery = 0
kMDItemFSLabel = 0
kMDItemFSName = "swapfile0"
kMDItemFSNodeCount = 0
kMDItemFSOwnerGroupID = 0
kMDItemFSOwnerUserID = 0
kMDItemFSSize = 67108864
kMDItemFSTypeCode = ""