それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

ファイル簡単検索にlocate コマンド。自分だけの検索インデックスを使う。

loccate便利

いままでfind に頼ってましたが、locateを覚えてからはlocateばかり使っています。locate食わず嫌いでした。反省してます。
locateコマンドもファイル検索コマンドです。find・grep/locateの大きな違いは、事前インデックス作成の有無です。locateは事前インデックスとまず覚えた。ちなみにfindはファイル名を、grepはファイルの中身を検索します。locate コマンドは事前にファイルをインデックスするので、検索がとても早く重宝します。ファイル数が多いときは、locateが有利です。locate にも欠点があります。一つは事前にインデックス化です。もう一つが対象ディレクトリの指定はインデックスで行う点です。必要です。インデックス作成すれば速いのですが、作成は手間ですね。対象ディレクトリ毎に検索インデックスを作るのも手間です。

検索インデックスはディレクトリ単位

検索インデックスはディレクトリ単位で作ることが出来ます。

データベースを分ける理由。

Rootからlocate のインデックスをシステム全体で作れる。全ファイルが検索対象になって便利。だけれどどのユーザーからも丸見えになる。そこれユーザー単位にインデックスを分ける。だからインデックスはユーザー毎に自分で作るのレス。

通常はmlocate

mlocate使ってれば間違いない。

ファイルのパーミッションを解決してくれるmlocate

locateは一度インデックするとユーザーが誰でも使えるため、別ユーザーにもファイル名が見えてしまう。mocateで問題解決。

mlocate はシステム全体をインデックスしても、ユーザーがアクセス可能なファイルだけが検索結果に出る。便利です。通常はmlocateを使うのが良いと思います。まれにmlocateが出来ない環境(cygwin・仮想ホスト・ルート権限持ってない)が存在して検索に四苦八苦しました。そこで自分でインデックスを作り活用する方法も知らなくてはなりませんでした。

locate (GNU findutils)

通常検索
locate PATTERN
インデックスファイルを指定して検索
locate --database=~/.locate.db PATTERN

複数指定も出来ます

locate --database=~/.locate.db:~/.project.db PATTERN

PATTERNには" * ", " ? "も使えます。

正規表現検索
locate -r REGEX_PATTERN

正規表現で検索ができるそうです ( man locate )

検索インデックスを省略すると・・・

locate --database=/path/to/database

で指定できますが、オプションを省略すると
デフォルト、LOCATE_PATH環境変数 から検索する。

LOCATE_PATH環境変数の使い方

export LOCATE_PATH=/path/to/database:/another/path/to/database2

と":"で区切ります。後述のprunepathと書式が違うので注意

検索インデックスを作り方。updatedb コマンド

ここまでで、検索インデックスの使い方を調べました。次は検索インデックスの作り方です。

検索インデックスを作るupdatedb

updatedb 

インデックス・ファイル名を指定。

updatedb --output=/path/to/database

インデックスに含めないファイル名を指定

updatedb --prunepaths="/path/to/exclude /another/path/to/exclude"

インデックスを作成するディレクトリ

updatedb --localpaths=/path/to/make/indexes

ホームディレクトリを検索しつつ .git または .hg(mercurial)は除外する

updatedb --localpaths=/home/takuya/sources --prunepaths='$(find /home/takuya/ -name ".hg")' --output=test.locate.db

オプション指定するのは面倒なので、省力化したい。

  1. aliasを使う
  2. 環境変数を使う
  3. /etc/updatadb.confを使う

の3通りが候補にある。aliasはいつでも出来る。update.confだとシステム全体で、個人用に使いたい今回の用途から外れちゃう。*1

環境変数で指定する。

.bashrc
export $PRUNEPATHS="$(find /home/takuya  -name ".hg") $PRUNEPATHS"
export $PRUNEPATHS="$(find /home/takuya  -name ".svn") $PRUNEPATHS"
export $PRUNEPATHS="$(find /home/takuya  -name ".git") $PRUNEPATHS"

を追記した。findutilsのlocateがフルパスにしかマッチさせないので、わざわざfindしてる。

cygwin なら windows の管理ファイルに興味がないので

export PRUNEPATHS="/home/takuya/AppData $PRUNEPATHS"
export PRUNEPATHS=" /home/takuya/Application\\ Data $PRUNEPATHS"
export PRUNEPATHS=" /home/takuya/Local\\ Settings  $PRUNEPATHS"
export PRUNEPATHS=" /home/takuya/Cookies $PRUNEPATHS"
export PRUNEPATHS=" /home/takuya/My\\ Documents $PRUNEPATHS"

なども書き足しておいた。

参考

man updatedb
man locate
http://d.hatena.ne.jp/holidays-l/20101204/p1

*1:/etc/updatedb.confを使うなら、各ユーザの~/updatedb.confをロードする設定を書けばいいと思う。試してない