読者です 読者をやめる 読者になる 読者になる

Mac/Linuxで全文検索する便利なスクリプト「nyamazu」作った

電波 Linux Apple関係

面倒くさい全文検索

 プログラムを書いていると、とあるキーワードがどのファイルの含まれているか全文検索をしたくなるときがあります。実はこれ、結構面倒で、例えばカレントディレクトリ以下のunkoという文字が含まれているファイルを探したいときは以下のように書く必要があります。

$ find . -type f | xargs grep "unko"

 うわー、面倒くさいです。というか覚えれない。鳥並の記憶力の私には覚えられないですよ。どんなコマンドだったっけ?と調べてる間に何を調べたいか忘れてしまうくらいには鳥並の記憶力です。

 というわけで、今回はこの問題を解決してみます。Mac OS X、Linuxでバージョンに依存なく動きます(多分)。一応Raspberry PiでもOKでした。WindowsのCygwinとかでも多分動くんじゃないかな(ダメかも)。例によって宇宙語が続くので、気になる方だけどうぞ。

全文検索スクリプト「nyamazu」

 よくつかうから、シェルスクリプト化しようかなと思いました。作る前に念のため調べてみたら、やっぱり同じこと考えている人がいました。

 というわけで、上記スクリプトを参考に自分の使いやすいように作り直してみました。中身は以下です。

 元のプログラムは気を使って、コマンドの絶対パスを指定していたりしたのですが、パス通ってるでしょということで省略。代わりにファイルに空白があるときにエラーになることをfind-print0オプション。xargs-0オプション追加して回避。grepiオプションつけて、大文字と小文字両方検索と、-nオプションで検索した文字のある文字番号を追加するようにしました。この辺はお好みでカスタマイズいただければよいかと思います。

 参考にしたサイトの人「fgr」と名付けていましたが、ネーミングに自信なく名前募集中とのことだったので、自分のスクリプトは勝手に「nyamazu」と名付けました。Webの全文検索システムの「namazu」というソフトをもじっただけです。そういえば「namazu」って全然聞かなくなっちゃいましたね、グーグルさんがいるからかな。

 上記スクリプトを nyamazu.shというファイルで保存して、以下のようなコマンドでパスの通ったディレクトリにシンボリックリンクを張りましょう。。

$ sudo ln -sf nyamazu.sh /usr/local/bin/nyamazu

 こうすれば、後はどこでも以下のようなコマンドで、全文検索ができます。1つ目の引数が探したい単語(下記の例はunko)で2つ目の引数が探したいディレクトリ(下記の例は/ スラルート、つまり全部)です。

$ nyamazu unko /

 1つ目の引数が空欄だと使い方が表示されます。2つ目の引数は省略可能で、省略した場合はカレントディレクトリを検索します。

 検索した結果は以下です。 f:id:karaage:20160427223106p:plain:w640

MacだとSpotlight (mdfind)が便利

 上記スクリプトはいちいち全ファイルを調べるので、ファイルが大量にあると劇遅君になります。MacだとSpotlight(Ctrl + spaceCommand + spaceででてくるやつ)で、高速に全文検索ができるのですが、これがターミナルでも使えます。コマンドは例えばunkoを検索したければ以下。

$ mdfind unko

 特定のディレクトリ(例えばカレントディレクトリ以下)だけ探したい場合は、以下です。

$ mdfind -onlyin . unko

 便利だし早い。あらかじめ検索対処のファイルをデータベース化しているので高速に検索ができるそうです。

まとめ

 汎用的に使えそうなスクリプト作ってみました。他には似たようなものとして、あらかじめデータベースファイルを作成して高速に検索するlocateとか、テキストエディタのvim上でファイルを横断的に検索できる標準コマンドの:vimgrepとかあります。vimgrepは良さそうだなと思ったのですが、自分の環境だと激遅でした。他にも、自分が知らないだけでもっといけてる便利なものが世の中にはあるかもしれません。誰か知っていたら教えてくださいw

 今回作ったスクリプトをscriptsというリポジトリ作ってGitHubにもあげてみました。色々便利なスクリプトできたらここに上げていこうかなと思います。こういうスクリプト集みたいなの一つ作っておくと色々便利かもしれませんね。

 

参考記事

UNIX findとxargsコマンドで-print0オプションを使う理由

Macのターミナルからファイルを高速に検索